我有两个表,其中只有一列相同。我正在尝试编写一个存储过程,该存储过程从传入的列名中提取一个值,但只存在于其中一个表中。这就是我写的:
IF EXISTS(
SELECT identifier FROM TableA WHERE identifier='12345')
SELECT ColumnWhichOnlyExistsInA FROM TableA WHERE identifier='12345'
ELSE
SELECT ColumnWhichOnlyExistsInA FROM TableB WHERE identifier='12345'
这给了我最后一行的'无效列名'错误,即使IF语句为真,它只应从TableA中提取内容。我注意到如果我用存储过程替换底部的两个SELECT语句做同样的事情,它的工作原理; SQL不会尝试执行IF为假的那个。
我想将所有内容保存在一个存储过程中。这样做的最佳方式是什么?
答案 0 :(得分:1)
您的查询无法进行COMPILE,因为编译器会检查相应表中是否存在要选择的列 - 因此IF语句永远不会被执行。
它在单独的存储过程中工作,因为它们是在运行时按需编译的,因此只会编译“工作”存储过程。
要解决此问题,请使用Dynamic SQL
DECLARE @SQLString varchar(max)
IF EXISTS (SELECT idenfier FROM TableA WHERE identifier='12345')
BEGIN
SET @SQLString = 'SELECT ColumnWhichOnlyExistsInA FROM TableA WHERE identifier=''12345'''
END
ELSE
BEGIN
SET @SQLString = 'SELECT ColumnWhichOnlyExistsInA FROM TableB WHERE identifier=''12345'''
END
EXECUTE sp_executesql @SQLString
答案 1 :(得分:0)
您是否尝试过查询架构作为第一次测试?例如 从information_schema.columns中选择table_name,其中column_name ='ColumnWhichOnlyExistsInA'
答案 2 :(得分:0)
在运行SQL之前,解析器将尝试解析SQL,这也意味着它将尝试检查所有引用列是否都在表中
例如,以下内容不起作用,因为表name1
sys.table
的列
IF EXISTS(SELECT 1 FROM sys.tables WHERE name='foo')
SELECT * from sys.objects where name= 's'
ELSE
SELECT * from sys.tables where name1= 's'
因此,如果TableB没有标识符作为列,则会出现错误