无法使用sp_MSforeachtable绑定获取Multipart标识符

时间:2014-08-07 14:12:07

标签: sql foreach multipart sp-msforeachtable

我正在使用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

我会继续努力,但我的想法已经不多了。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

查询中的?将替换为表的带引号的模式限定名称。它不会用引号括起来,因此您的查询等同于:

SELECT ...
WHERE TABLE_NAME = [dbo].[YourTable]
...
SELECT @DB As [DataBase], [dbo].[YourTable] As [Table], @Names As [Columns]

这显然会产生错误。

您需要在?周围添加引号,以便将其视为字符串。但是,由于TABLE_NAME列未包含架构名称且未引用,因此您的查询无法正常工作。

要使查询按预期工作,您需要合并TABLE_SCHEMATABLE_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
;