我正在使用sp_MSForeachtable
检索所有表的列名并将列名连接在一个字符串中。我正在使用以下查询。我已经执行相同的操作,通过一个表的变量提供参数并且工作正常,但是当从SP执行时它失败并出现错误“多部分标识符”dbo.TableNm“无法绑定。”
DECLARE @query nvarchar(max)
SELECT @query =
'DECLARE @Names VARCHAR(255)
DECLARE @DB VARCHAR(255)
SELECT @Names = COALESCE(@Names + '', '', '''') + COLUMN_NAME FROM Information_Schema.COLUMNS
WHERE TABLE_NAME = ?
SELECT TOP 1 @DB = TABLE_CATALOG FROM Information_Schema.COLUMNS
WHERE TABLE_NAME = ?
SELECT @DB AS [DataBase], ? AS [Table], @Names AS [Columns]'
EXEC sp_MSforeachtable @query
我认为错误可能与在不同数据库中具有相同名称的多个表相关联,因此我尝试预先修复数据库但我仍然得到相同的错误。
DECLARE @query nvarchar(max)
SELECT @query =
'DECLARE @Names VARCHAR(255)
DECLARE @DB VARCHAR(255)
DECLARE @TableNm VARCHAR(255) = ?
SET @DB = ''People_Directory''
SELECT @Names = COALESCE(@Names + '', '', '''') + COLUMN_NAME FROM Information_Schema.COLUMNS
WHERE TABLE_NAME = @TableNm
AND TABLE_CATALOG = @DB
SELECT @DB AS [DataBase], @TableNm AS [Table], @Names AS [Columns]'
EXEC sp_MSforeachtable @query
我会继续努力,但我的想法已经不多了。有什么想法吗?
答案 0 :(得分:0)
查询中的?
将替换为表的带引号的模式限定名称。它不会用引号括起来,因此您的查询等同于:
SELECT ...
WHERE TABLE_NAME = [dbo].[YourTable]
...
SELECT @DB As [DataBase], [dbo].[YourTable] As [Table], @Names As [Columns]
这显然会产生错误。
您需要在?
周围添加引号,以便将其视为字符串。但是,由于TABLE_NAME
列未包含架构名称且未引用,因此您的查询仍无法正常工作。
要使查询按预期工作,您需要合并TABLE_SCHEMA
和TABLE_NAME
列,并确保在与当前表名称进行比较之前引用这些值:< / p>
DECLARE @query nvarchar(max)
SELECT @query =
'DECLARE @Names VARCHAR(255)
DECLARE @DB VARCHAR(255)
SELECT @Names = COALESCE(@Names + '', '', '''') + COLUMN_NAME FROM Information_Schema.COLUMNS
WHERE QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME) = ''?''
SELECT TOP 1 @DB = TABLE_CATALOG FROM Information_Schema.COLUMNS
WHERE QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME) = ''?''
SELECT @DB AS [DataBase], ''?'' AS [Table], @Names AS [Columns]'
EXEC sp_MSforeachtable @query
修改强>
您实际上并不需要使用sp_MSforeachtable
来执行此操作。使用this article中的一种方法,您可以在一个查询中检索此信息:
SELECT
T.TABLE_CATALOG As [DataBase],
QUOTENAME(T.TABLE_SCHEMA) + '.' + QUOTENAME(T.TABLE_NAME) As [Table],
STUFF(
(
SELECT ', ' + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS As C
WHERE C.TABLE_CATALOG = T.TABLE_CATALOG
And C.TABLE_SCHEMA = T.TABLE_SCHEMA
And C.TABLE_NAME = T.TABLE_NAME
ORDER BY C.ORDINAL_POSITION
FOR XML PATH(''), TYPE
).value('.', 'varchar(max)')
, 1, 1, '') As [Columns]
FROM
INFORMATION_SCHEMA.TABLES As T
;