如何为表中的任何列选择类似字符串的记录?

时间:2013-08-30 12:26:24

标签: sql sql-server tsql xquery sqlxml

我知道我可以使用like %termToFind%在t-sql的表中的一列中搜索一个术语。我知道我可以用表格列出所有列:

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

如何在表格的每一列上执行类似的比较?我有一个非常大的表,所以我不能为每列拼出LIKE

3 个答案:

答案 0 :(得分: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)

我在这里使用动态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以进行查询没有任何开销。

答案 2 :(得分:0)

如果有人正在寻找PostgreSQL解决方案:

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

将选择所有包含' your_value'在任何专栏中。没有尝试过任何其他数据库。

不幸的是,这可以将所有列组合成文本字符串,然后在该字符串中搜索一个值,因此我不知道如何使其匹配"整个单元格"只要。如果任何单元格的任何部分匹配' your_value'。

,它将始终匹配