我知道我可以使用like %termToFind%
. 而且我知道我可以通过以下方式获取表中的所有列:
SELECT *
FROM MyDataBaseName.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'MyTableName`
如何对表的每一列执行类似的比较?我有一张很大的桌子,所以我不能只拼出LIKE
每一列。
我知道我可以使用like %termToFind%
. 而且我知道我可以通过以下方式获取表中的所有列:
SELECT *
FROM MyDataBaseName.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'MyTableName`
如何对表的每一列执行类似的比较?我有一张很大的桌子,所以我不能只拼出LIKE
每一列。
与往常一样,我会为此建议 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。
完整的信用 - 这个答案最初是由另一个用户发布的,并被删除。我认为这是一个很好的答案,所以我重新添加它。
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 进行查询时没有开销。
如果有人正在寻找 PostgreSQL 解决方案:
SELECT * FROM table_name WHERE position('your_value' IN (table_name.*)::text)>0
将选择任何列中包含“your_value”的所有记录。没有尝试使用任何其他数据库。
不幸的是,这可以将所有列组合到一个文本字符串,然后在该字符串中搜索一个值,所以我不知道如何让它只匹配“整个单元格”。如果任何单元格的任何部分与“your_value”匹配,它将始终匹配。