0

我的一个存储过程中有一个典型的“无效列名”,但我很难理解任何流行的解决方法如何解决我的问题:(

我的存储过程执行以下操作:

IF EXISTS (SELECT * FROM sysobjects o 
           JOIN syscolumns c 
           ON o.id = c.id
           WHERE o.Name = 'Table_A'
           AND c.Name = 'Column_A')

    BEGIN
       SELECT * FROM Table_B
       JOIN Table_A
       ON Table_B.Column_B = Table_A.Column_B
       WHERE Table_A.Column_A = 1
       FOR XML AUTO
   END

ELSE
    --Do something completely different

所以...我收到 Table_A.Column_A 无效的错误,但我还能如何在查询中引用它?我尝试使用动态 SQL 来创建直到“FOR XML AUTO”部分的字符串,然后使用存储过程来标记“FOR XML AUTO”部分,这可能是问题所在,但我得到了同样的错误.

为了回答我相信有些人会问的问题,查询:

SELECT * FROM sysobjects o 
           JOIN syscolumns c 
           ON o.id = c.id
           WHERE o.Name = 'Table_A'
           AND c.Name = 'Column_A'

当 Column_A 不在 Table_A 中时,不会产生任何结果。

并且...不,我不能更改数据库结构,它必须是这种解决方法,因为表可能包含也可能不包含此列,具体取决于数据库实例,我需要一个“包罗万象”.. .

有什么好主意吗?

4

1 回答 1

1

问题是由于子查询中的引用,除非您在数据中存在该列,否则您的代码将不会解析。在if运行时评估。所有查询都必须在编译时解析。

解决这个问题(据我所知)的唯一方法是动态 SQL。

这是一个有效的代码示例:

   declare @x xml;
   declare @sql nvarchar(max) = '
   select @x = (SELECT *
             FROM INFORMATION_SCHEMA.tables t JOIN
                  INFORMATION_SCHEMA.COLUMNS c
                  ON t.TABLE_NAME = c.TABLE_NAME
             WHERE t.TABLE_SCHEMA = ''dbo''
             FOR XML AUTO
            )';

   exec sp_executesql @sql, N'@x xml output', @x = @x output;

   select @x;

然后,您可以将您的if条件放在它上面并根据您的实际查询对其进行修改。

于 2013-05-30T14:13:51.030 回答