使用SQL Server 2005执行以下语句(我的测试通过SSMS)会在首次执行时成功,并在后续执行时失败。
IF OBJECT_ID('tempdb..#test') IS NULL
CREATE TABLE #test ( GoodColumn INT )
IF 1 = 0
SELECT BadColumn
FROM #test
这意味着当脚本被“编译”时,我正在将我在select语句中访问的列与表中存在的列进行比较。出于我的目的,这是不合需要的功能我的问题是,是否有任何可以做的事情,以便这些代码在每次运行时都能成功执行,或者如果不可能,也许有人可以解释为什么所展示的功能是可取的。我目前唯一的解决方案是使用EXEC或select *包装select,但我不喜欢这两种解决方案。
由于
答案 0 :(得分:3)
如果你把:
IF OBJECT_ID('tempdb..#test') IS NOT NULL
DROP TABLE #test
GO
一开始,问题就会消失,因为批次将在#test表存在之前解析。
您所要求的是系统识别“1 = 0”将始终评估为false。如果它是真的(对于大多数现实条件可能是这种情况),那么你可能想知道你将要运行会导致失败的东西。
如果删除临时表,然后创建执行相同操作的存储过程:
CREATE PROC dbo.test
AS
BEGIN
IF OBJECT_ID('tempdb..#test') IS NULL
CREATE TABLE #test ( GoodColumn INT )
IF 1 = 0
SELECT BadColumn
FROM #test
END
然后这将很乐意创建,您可以根据需要多次运行它。
罗布
答案 1 :(得分:0)
从程序员的角度来看这种行为是否“令人满意”当然值得商榷 - 它基本上归结为静态类型语言和动态类型语言之间的区别。从性能的角度来看,这是可取的,因为SQL Server需要完整的信息才能编译和优化执行计划(以及缓存执行计划)。
总之,T-SQL 不是是一种解释型或动态类型的语言,因此您无法编写这样的代码。您可以选择使用EXEC,也可以使用其他语言并在其中嵌入SQL查询。
答案 2 :(得分:0)
在这些情况下也会出现此问题:
IF 1 = 1
select dummy = GETDATE() into #tmp
ELSE
select dummy = GETDATE() into #tmp
虽然第二个语句从未执行过,但会发生同样的错误。 似乎查询引擎第一级验证忽略所有条件语句。
答案 3 :(得分:0)
您说您在后续请求中遇到问题,这是因为该对象已经退出。它建议您在完成后尽快删除临时表。
详细了解临时表的性能: SQL Server performance.com