【发布时间】:2012-07-24 13:49:07
【问题描述】:
我有一个 CTE,其中生成了 SELECT 语句,但 SQL Server (2012) 不允许在其上调用 EXEC。这是查询:
DECLARE @guidToFind uniqueidentifier = 'E4069560-091A-4026-B519-104F1C7693B3';
WITH GuidCols (TableName, ColName, Query) As
(
SELECT
C.TABLE_NAME,
C.COLUMN_NAME,
'SELECT ' +
QUOTENAME(C.TABLE_NAME) + '.' +
QUOTENAME(C.COLUMN_NAME) + '
FROM ' +
QUOTENAME(C.TABLE_NAME) + '
WHERE ' +
QUOTENAME(C.COLUMN_NAME) + ' = ''' + cast(@guidToFind AS VARCHAR(50))+
''''
FROM
INFORMATION_SCHEMA.COLUMNS C
INNER JOIN INFORMATION_SCHEMA.TABLES T
ON C.TABLE_NAME = T.TABLE_NAME AND
T.TABLE_TYPE = 'BASE TABLE'
WHERE
C.DATA_TYPE = 'uniqueidentifier'
)
-- SELECT * FROM
EXEC( GuidCols.Query )
如果我在 CTE 之后取消注释 SELECT 语句,问题并没有解决。
此查询的目的是查找数据库中 GUID 的所有实例。目前我正在使用像this 这样的脚本来解决这个问题。但是,如果不使用集合操作和其他技术迭代行,我会更乐意解决这个问题。
【问题讨论】:
-
EXISTS如果您只想知道包含该值的表和列,则可能是查找 GUID 实例的更有效方法。您可以组装一个单一的查询UNIONs 所有结果,然后EXECUTE该字符串。 -
@HABO 感谢您的提示。你能解释一下我在哪里可以使用
EXISTS吗?在第二部分中,您的意思是制作一串硬编码的表和列名称,例如'SELECT ''[table1]'', ''[Col5]'' UNION ALL SELECT ''[table3]'', ''[Col8]'''? -
@HABO 我目前正在以这种方式实现这一目标:gist.github.com/3180402 但如果我可以使用集合操作而不是循环,我会更开心
-
在您的 github 示例中,您添加了
DISTINCT,这样如果在给定的表和列中找到 GUID 一次或多次,您只会获得一行。如果列包含 GUID 的实例,select C.Table_Name, C.Column_Name from C.Table_Name where exists ( select 42 from C.Table_Name where C.Column_Name = @GuidToFind )将返回表名和列名。它使优化器清楚地知道,您并不关心该值被发现的频率,只要它存在即可。如果您将UNION对每个表和列进行一系列此类查询,您将获得 GUID 所在位置的列表。
标签: sql sql-server common-table-expression