2013-08-30 48 views
6

我知道我可以通過使用like %termToFind%在t-sql的表中的一列中搜索一個術語。我知道我可以得到所有表中的列本:如何爲表中的任何列選擇類似字符串的記錄?

SELECT * 
FROM MyDataBaseName.INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = N'MyTableName` 

我怎樣才能在每個表的列進行類似comprparison?我有一張非常大的桌子,所以我不能爲每列列出LIKE

+3

如果您認爲將來可能會做這樣的事情,那麼您應該查看SQL Server的全文搜索功能。 @ RomanPekar的XML方法可以工作,但它不能真正使用索引,所以不會很快。這很好,如果你偶爾會這樣做,但如果你需要這個在線用戶查詢,你的服務器會很快陷入困境。 – RBarryYoung

+0

@RBarryYoung非常真實 –

回答

10

一如既往,我會爲此建議xml(如果SQL Server本身支持它,我會建議使用JSON :))。您可以嘗試使用此查詢,雖然它可以在大量的行執行不那麼好:

;with cte as (
    select 
     *, 
     (select t.* for xml raw('data'), type) as data 
    from test as t 
) 
select * 
from cte 
where data.exist('data/@*[local-name() != "id" and contains(., sql:variable("@search"))]') = 1 

看到sql fiddle demo更詳細的例子。

重要說明Alexander Fedorenko的評論:應該理解的是contains功能是區分大小寫的,並且使用的XQuery默認Unicode代碼點排序規則的字符串比較

更一般的方式是使用動態SQL的解決方案:

declare @search nvarchar(max) 
declare @stmt nvarchar(max) 

select @stmt = isnull(@stmt + ' or ', '') + quotename(name) + ' like @search' 
from sys.columns as c 
where c.[object_id] = object_id('dbo.test') 
-- 
-- also possible 
-- 
-- select @stmt = isnull(@stmt + ' or ', '') + quotename(column_name) + ' like @search' 
-- from INFORMATION_SCHEMA.COLUMNS 
-- where TABLE_NAME = 'test' 

select @stmt = 'select * from test where ' + @stmt 

exec sp_executesql 
    @stmt = @stmt, 
    @params = N'@search nvarchar(max)', 
    @search = @search 

sql fiddle demo

+1

+1 - 很酷的答案。 – Devart

+0

@Devart謝謝,添加動態SQL解決方案 –

+0

恕我直言:'sys.columns'不包含隱藏連接與'INFORMATION_SCHEMA.COLUMNS'相比:'SELECT c.name FROM sys.columns c WHERE OBJECT_ID('dbo.test' )= c。[object_id]' – Devart

1

我在這裏使用動態SQL。

完整學分 - 這個答案最初由其他用戶發佈,並被刪除。我認爲這是一個很好的答案,所以我重新添加它。

DECLARE @sql NVARCHAR(MAX); 
DECLARE @table NVARCHAR(50); 
DECLARE @term NVARCHAR(50); 

SET @term = '%term to find%'; 
SET @table = 'TableName'; 
SET @sql = 'SELECT * FROM ' + @table + ' WHERE ' 

SELECT @sql = @sql + COALESCE('CAST('+ column_name 
    + ' as NVARCHAR(MAX)) like N''' + @term + ''' OR ', '') 
FROM INFORMATION_SCHEMA.COLUMNS WHERE [TABLE_NAME] = @table 

SET @sql = @sql + ' 1 = 0' 
SELECT @sql 
EXEC sp_executesql @sql 

的XML答案是清潔劑(我喜歡動態SQL僅在必要時),但這樣做的好處是,它會利用你對你的表的任何索引,並且沒有開銷在構建XML的CTE查詢。

+0

這可能是sql注入的主題 - 這就是爲什麼我使用帶參數的sp_executesql –

0

萬一有人找PostgreSQL的解決方案:

SELECT * FROM table_name WHERE position('your_value' IN (table_name.*)::text)>0 

將選擇具有「your_value」在所有列的所有記錄。沒有嘗試過任何其他數據庫。

不幸的是,這個工作原理是將所有的列組合到一個文本字符串中,然後在該字符串中搜索一個值,所以我不知道如何使它與「整個單元格」匹配。如果任何單元格的任何部分都匹配'your_value',它將始終匹配。

相關問題