Sql 如何在表的所有列中动态查找关键字
我希望能够在表的所有列中动态查找特定关键字。脚本的目的是只需要更改关键字和表名,而不需要知道表的所有列是什么 这意味着以下代码不是令人满意的解决方案: […]其中字段1、字段2、字段3、字段4中的“关键字”。。。[……] 我能够使用子查询动态检索表的所有列名。但是,子查询中的IN语句返回一个空结果 然后,我创建了一个新的子查询,它以逗号分隔的列表格式返回列列表。但结果也是空的 以下是迄今为止的脚本:Sql 如何在表的所有列中动态查找关键字,sql,sql-server,tsql,Sql,Sql Server,Tsql,我希望能够在表的所有列中动态查找特定关键字。脚本的目的是只需要更改关键字和表名,而不需要知道表的所有列是什么 这意味着以下代码不是令人满意的解决方案: […]其中字段1、字段2、字段3、字段4中的“关键字”。。。[……] 我能够使用子查询动态检索表的所有列名。但是,子查询中的IN语句返回一个空结果 然后,我创建了一个新的子查询,它以逗号分隔的列表格式返回列列表。但结果也是空的 以下是迄今为止的脚本: DECLARE @DATABASE_NAME VARCHAR(128) DECLARE @SCH
DECLARE @DATABASE_NAME VARCHAR(128)
DECLARE @SCHEMA_NAME VARCHAR(128)
DECLARE @TABLE_NAME VARCHAR(128)
DECLARE @KEYWORD VARCHAR(128)
DECLARE @QUERY01 VARCHAR(MAX)
DECLARE @QUERY02 VARCHAR(MAX)
DECLARE @SUBQUERY01 VARCHAR(MAX)
DECLARE @SUBQUERY02 VARCHAR(MAX)
SET @DATABASE_NAME = '[xxx]'
SET @SCHEMA_NAME = '[dbo]'
SET @TABLE_NAME = 'tblCustomers'
SET @KEYWORD = 'Jean'
SET @SUBQUERY01 = 'SELECT Name FROM sys.columns WHERE object_id = (SELECT
object_id FROM sys.tables WHERE name = ''' + @TABLE_NAME + ''')'
SET @SUBQUERY02 = 'SELECT SUBSTRING((SELECT '', '' + Name FROM
sys.columns WHERE object_id = (SELECT object_id FROM sys.tables WHERE
name = ''' + @TABLE_NAME + ''') FOR XML PATH('''')), 2, 1000000)'
SET @QUERY01 = 'SELECT * FROM ' + @DATABASE_NAME + '.' + @SCHEMA_NAME +
'.' + @TABLE_NAME
-- + ' WHERE ''' + @KEYWORD + ''' IN (FirstName, LastName)' -- Works
+ ' WHERE ''' + @KEYWORD + ''' IN (' + @SUBQUERY01 + ')'
SET @QUERY02 = 'SELECT * FROM ' + @DATABASE_NAME + '.' + @SCHEMA_NAME +
'.' + @TABLE_NAME
+ ' WHERE ''' + @KEYWORD + ''' IN (' + @SUBQUERY02 + ')'
EXEC (@SUBQUERY01) -- OK (List of column names, one per row)
EXEC (@SUBQUERY02) -- OK (List of column names, comma-separated values)
EXEC (@QUERY01) -- NOK (Empty result)
EXEC (@QUERY02) -- NOK (Empty result)
我希望脚本返回其中一列中包含关键字的所有行。例如,以下代码可以正常工作:
SELECT * FROM [xxx].[dbo].tblCustomers
WHERE 'Jean' IN (FirstName, LastName)
这可能就是你想要的。注意:我将搜索限制为仅查找字符串类型的列,使用QUOTENAME和parametrise正确引用对象语句:
DECLARE @Schema sysname,
@Table sysname,
@Keyword varchar(100);
DECLARE @SQL nvarchar(MAX);
SET @Schema = N'dbo';
SET @Table = N'icp_yyclient';
SET @Keyword = 'Smith';
SET @SQL = N'SELECT *' + NCHAR(13) + NCHAR(10) +
N'FROM ' + QUOTENAME(@Schema) + N'.' + QUOTENAME(@Table) + NCHAR(13) + NCHAR(10) +
N'WHERE @Keyword IN (' + STUFF((SELECT N',' + QUOTENAME(C.[name])
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
JOIN sys.schemas s ON t.schema_id = s.schema_id
JOIN sys.types ct ON c.system_type_id = ct.system_type_id
WHERE t.[name] = @Table
AND s.[name] = @Schema
AND ct.[name] IN (N'varchar',N'char',N'nvarchar',N'nchar',N'sysname')
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,1,N'') + N');';
PRINT @SQL; --Your best friend
EXEC sp_executesql @SQL, N'@Keyword varchar(100)', @Keyword;
这可能就是你想要的。注意:我将搜索限制为仅查找字符串类型的列,使用QUOTENAME和parametrise正确引用对象语句:
DECLARE @Schema sysname,
@Table sysname,
@Keyword varchar(100);
DECLARE @SQL nvarchar(MAX);
SET @Schema = N'dbo';
SET @Table = N'icp_yyclient';
SET @Keyword = 'Smith';
SET @SQL = N'SELECT *' + NCHAR(13) + NCHAR(10) +
N'FROM ' + QUOTENAME(@Schema) + N'.' + QUOTENAME(@Table) + NCHAR(13) + NCHAR(10) +
N'WHERE @Keyword IN (' + STUFF((SELECT N',' + QUOTENAME(C.[name])
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
JOIN sys.schemas s ON t.schema_id = s.schema_id
JOIN sys.types ct ON c.system_type_id = ct.system_type_id
WHERE t.[name] = @Table
AND s.[name] = @Schema
AND ct.[name] IN (N'varchar',N'char',N'nvarchar',N'nchar',N'sysname')
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,1,N'') + N');';
PRINT @SQL; --Your best friend
EXEC sp_executesql @SQL, N'@Keyword varchar(100)', @Keyword;
小心,这是非常容易注入的,你应该在动态SQL中引用你的对象,并对你的参数进行参数化。添加一个print@QUERY01并验证查询你还需要检查数据类型,否则数字列将失败。你正在将@SUBQUERY01 text而不是它的结果添加到@QUERY01小心,这是非常容易注入的,您应该引用对象,并在动态SQL中对参数进行参数化。添加一个打印@QUERY01并验证查询您还需要检查数据类型,否则数字列将失败。您正在将@SUBQUERY01文本而不是其结果添加到@QUERY01