2012-01-11 97 views
17

我發現自己處在一個我正在工作的數據庫中,每個表都有大量的列。我對我正在查找哪些數據有所瞭解,但我不知道它所在的列,並且需要使用like以查找我需要的確切數據(並且必須對多組數據重複此任務)。適用於所有列而不指定所有列名稱?

有沒有辦法像笛卡爾選擇一樣申請?

下應該解釋,我想怎樣做一個好一點的(即使它的語法荒謬):

select 
    * 
from  
    a_table 
where 
    * like '%x%' 

編輯

請注意,我沒有使用意圖在任何報告中都可以選擇cartesion--這裏的目的是幫助我確定需要放入查詢的相關列,並幫助我熟悉數據庫。

+1

這是一個有趣的問題。我的背景是bash命令,所以我想通過(1)grep然後(2)awk獲取數據。以這種方式,你會grep很多(甚至太多),然後用額外的grep或awk語句進行過濾。我很驚訝SQL沒有內置的'grep'功能。 – philshem 2013-10-28 09:44:48

回答

13

一般 - 它不可能以合理的方式(沒有DB元數據挖),但如果你知道列的名稱,你可以使用招這樣的:

select 
    YourTable.* 
FROM YourTable 
JOIN 
( 
    select 
     id, 
     ISNULL(column1,'')+ISNULL(Column2,'')+...+ISNULL(ColumnN,'') concatenated 
     FROM YourTable 
) T ON T.Id = YourTable.Id 
where t.concatenated like '%x%' 

OR如果搜索詞

- 使用FTS的能力,因爲上查詢是性能殺手

+1

性能不是這樣的問題,因爲我是開發數據庫上的唯一用戶,這是一次性的任務,欣賞儘管 – Codingo 2012-01-11 07:00:48

+0

如果是這樣 - 那麼或動態查詢 - 你甚至不必知道列名稱或我的變體 – 2012-01-11 07:02:32

+1

花了些功夫去了解你在這裏做什麼,但現在我喜歡這個解決方案。不勝感激! – Codingo 2012-01-11 07:14:42

4

不,這不適用於SQL。這也被認爲是不好的做法,儘管我可以在你的場景中看到用例。最好的辦法是到腳本在您最喜歡的語言通過檢索所有的列名的列表,然後用像執行任何一個單獨的查詢,結合了這一切的每一列或單個大型查詢:

select 
    * 
from 
    a 
where 
    a.column_1 like '%blah%' or 
    a.column_2 like '%blah%'; 

或,單獨的查詢:

select 
    * 
from 
    a 
where 
    a.column_1 like '%blah%' 

select 
    * 
from 
    a 
where 
    a.column_2 like '%blah%' 
7

有一個類似的討論here

有沒有直接的方法,你必須這樣做以這種方式:

SELECT Name, Age, Description, Field1, Field2 
FROM MyTable 
WHERE Name LIKE 'Something%' OR Description LIKE 'Something%' OR Field1 LIKE 'Something%' OR Field2 LIKE 'Something%' 

一張貼在該論壇的解決方案是這樣的,它使用動態SQL:

CREATE PROCEDURE TABLEVIEWSEARCH @TABLENAME  VARCHAR(60),@SEARCHSTRING VARCHAR(50) 
-- EXEC TABLEVIEWSEARCH 'GMACT','demo' 
-- EXEC TABLEVIEWSEARCH 'TABLEORVIEW','TEST' 
AS 
SET NOCOUNT ON 
DECLARE @SQL  VARCHAR(500), 
@COLUMNNAME  VARCHAR(60) 

CREATE TABLE #RESULTS(TBLNAME VARCHAR(60),COLNAME VARCHAR(60),SQL VARCHAR(600)) 
SELECT 
    SYSOBJECTS.NAME AS TBLNAME, 
    SYSCOLUMNS.NAME AS COLNAME, 
    TYPE_NAME(SYSCOLUMNS.XTYPE) AS DATATYPE 
    INTO #TMPCOLLECTION 
    FROM SYSOBJECTS 
     INNER JOIN SYSCOLUMNS ON SYSOBJECTS.ID=SYSCOLUMNS.ID 
    WHERE SYSOBJECTS.NAME = @TABLENAME 
    AND TYPE_NAME(SYSCOLUMNS.XTYPE) IN ('VARCHAR','NVARCHAR','CHAR','NCHAR') 
    ORDER BY TBLNAME,COLNAME 

DECLARE C1 CURSOR FOR 
SELECT COLNAME FROM #TMPCOLLECTION ORDER BY COLNAME 
OPEN C1 
FETCH NEXT FROM C1 INTO @COLUMNNAME 
WHILE @@FETCH_STATUS <> -1 
    BEGIN 
     --SET @SQL = 'SELECT ''' + @TABLENAME + ''' AS TABLENAME,''' + @COLUMNNAME + ''' AS COLUMNNAME,* FROM ' + @TABLENAME + ' WHERE ' + @COLUMNNAME + ' LIKE ''%' + @SEARCHSTRING + '%''' 
     SET @SQL = 'IF EXISTS(SELECT * FROM [' + @TABLENAME + '] WHERE [' + @COLUMNNAME + '] LIKE ''%' + @SEARCHSTRING + '%'') INSERT INTO #RESULTS(TBLNAME,COLNAME,SQL) VALUES(''' + @TABLENAME + ''',''' + @COLUMNNAME + ''','' SELECT * FROM [' + @TABLENAME + '] WHERE [' + @COLUMNNAME + '] LIKE ''''%' + @SEARCHSTRING + '%'''''') ;' 
     PRINT @SQL 
     EXEC (@SQL) 
FETCH NEXT FROM C1 INTO @COLUMNNAME 
    END 
CLOSE C1 
DEALLOCATE C1 

SELECT * FROM #RESULTS 

GO 
CREATE PROCEDURE TABLEVIEWSEARCH2 @TABLENAME  VARCHAR(60),@SEARCHSTRING VARCHAR(50) 
-- EXEC TABLEVIEWSEARCH2 'GMACT','SOURCE' 
-- EXEC TABLEVIEWSEARCH2 'TABLEORVIEW','TEST' 
AS 
BEGIN 
SET NOCOUNT ON 
DECLARE @FINALSQL  VARCHAR(MAX), 
@COLUMNNAMES  VARCHAR(MAX) 
SET @FINALSQL = 'SELECT * FROM [' + @TABLENAME + '] WHERE 1 = 2 ' 
SELECT 
    @FINALSQL = @FINALSQL + ' OR [' + SYSCOLUMNS.NAME + '] LIKE ''%' + @SEARCHSTRING + '%'' ' 

    FROM SYSCOLUMNS 
    WHERE OBJECT_NAME(id) = @TABLENAME 
    AND TYPE_NAME(SYSCOLUMNS.XTYPE) IN ('VARCHAR','NVARCHAR','CHAR','NCHAR') 
    ORDER BY COLID 

PRINT @FINALSQL 
EXEC(@FINALSQL) 
END --PROC 

我已在包含以下數據的員工表上對此進行了測試:

enter image description here

運行下面的語句

EXEC TABLEVIEWSEARCH2 'employee','2'

導致:

2 1 eng2 
4 2 dev2 
7 3 sup2 
9 4 qa2 

我以爲我會提供一些這方面的更多的例子在行動上,因爲上面的EMP表有一個字段它在哪裏搜索數據。

這是一個待辦事項數據庫中的任務表: enter image description here

搜索短語en:(突出的單元格,其中的數據進行匹配)

EXEC TABLEVIEWSEARCH2 'task','en'

enter image description here

3

你可以試試像這樣的東西,但如果你的表格真的很大,你可能會遇到一些麻煩,因爲它會創建一個你的enti的XML重新編制表格,然後查詢搜索字符串的XML。輸出是找到字符串的列名。

;with C(TableXML) as 
(
    select * 
    from YourTable 
    for xml path('T'), type 
) 
select distinct T.X.value('local-name(.)', 'sysname') as ColumnName 
from C 
    cross apply C.TableXML.nodes('/T/*') as T(X) 
where T.X.value('.', 'varchar(max)') like '%x%' 

http://data.stackexchange.com/stackoverflow/query/58934/new

2

感謝南大:)

這裏是我的瘦身腳本:

use a_database 

declare 
    @TableName as nvarchar(50) = 'a_table', 
    @FilterContition as nvarchar(50) = 'like ''%x%''', 
    @ColumnName as nvarchar(100), 
    @ColumnCursor as cursor, 
    @Sql as nvarchar(4000) 

set @ColumnCursor = cursor for 
    select distinct c.name 
    from sys.objects as o 
    inner join sys.columns as c 
     on o.object_id = c.object_id 
    where o.name = @TableName 
    and type_name(c.user_type_id) in ('VARCHAR','NVARCHAR','CHAR','NCHAR') 

open @ColumnCursor 
fetch next from @ColumnCursor into @ColumnName 
set @Sql = 'select * from ' + @TableName + ' where ' + @ColumnName + ' ' + @FilterContition 
while @@fetch_status = 0 
begin 
    fetch next from @ColumnCursor into @ColumnName 
    set @Sql = @Sql + ' and ' + @ColumnName + ' ' + @FilterContition 
end 
close @ColumnCursor 
deallocate @ColumnCursor 

exec(@Sql) 

它使用: - 動態SQL - 光標 - 數據庫的元數據

0
Create PROCEDURE dbo.sp_FindStringInTable @stringToFind VARCHAR(100), @table sysname 
AS 

BEGIN TRY 
    DECLARE @sqlCommand varchar(max) = 'SELECT * FROM [' + @table + '] WHERE ' 

    SELECT @sqlCommand = @sqlCommand + '[' + COLUMN_NAME + '] LIKE ''' + @stringToFind + ''' OR ' 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = @table 
    AND DATA_TYPE IN ('char','nchar','ntext','nvarchar','text','varchar') 

    SET @sqlCommand = left(@sqlCommand,len(@sqlCommand)-3) 
    EXEC (@sqlCommand) 
    PRINT @sqlCommand 
END TRY 

BEGIN CATCH 
    PRINT 'There was an error. Check to make sure object exists.' 
    PRINT error_message() 
END CATCH 

--then調用這個

EXEC sp_FindStringInTable 'yoursearchitem', 'tablename' 
-1

一個簡單的方法:1。 從INFORMATION_SCHEMA選擇COLUMN_NAME。COLUMNS 其中TABLE_NAME = 'your_table'

  • 複製的結果粘貼到Excel工作表單元格B1
  • 類型ISNULL(A1
  • 型在細胞, '')+在小區C1
  • 類型= A1 & B1 & C1在細胞D1
  • 將細胞A1和C1和D1向下
  • 複製粘貼列d到SQL

  • 添加SELECT * FROM your_table那裏(開頭

  • 刪除+末
  • 添加)末LIKE '%x%的'
  • 執行
  • Excel是你的朋友!

    相關問題