2

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

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

4

1 回答 1

0

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

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

这显然会产生错误。

您需要在 周围添加引号,?以便将其视为字符串。但是,您的查询仍然不起作用,因为该TABLE_NAME列不包含架构名称,并且没有被引用。

要使查询按预期工作,您需要组合TABLE_SCHEMATABLE_NAME列,并确保在与当前表名进行比较之前引用这些值:

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来执行此操作。使用本文中的一种方法,您可以在单个查询中检索此信息:

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
;
于 2014-08-07T16:09:21.343 回答