2009-08-29 158 views
3

使用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或选择*来包装选择,但我不喜欢那些解决方案。

感谢

回答

0

无论这种行为是从一个程序员的角度是值得商榷的当然是“希望” - 它基本上可以归结为静态类型和动态类型语言之间的差异。从性能角度来看,这是可取的,因为SQL Server需要完整的信息才能编译和优化执行计划(以及缓存执行计划)。

总之,T-SQL是而不是是一种解释型或动态类型的语言,因此您不能编写这样的代码。您的选择是使用EXEC,或者使用其他语言并在其中嵌入SQL查询。

3

如果你把:

IF OBJECT_ID('tempdb..#test') IS NOT NULL 
    DROP TABLE #test 
GO 

比赛一开始,那么这个问题就会迎刃而解,因为#TEST表存在之前分批将得到解析。

你所要求的是让系统认识到“1 = 0”总会被评估为假。如果它是真的(对于大多数现实生活条件来说可能是这种情况),那么你可能会想知道你将要运行一些会导致失败的事情。

如果删除临时表,然后创建一个存储过程,做同样的:

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 

那么这会很乐意被创建,并且只要你喜欢,你可以运行它多次。

罗布

+0

我在SQL尝试这两种解决方案都和失败,“无效的列名称BadColumn“。“ – 2009-08-29 06:30:40

+0

如果临时对象不存在,那么我可以创建这个dbo.test proc,并重复运行它。如果临时对象存在,那么你会得到错误。 – 2009-08-29 07:06:33

+0

+1为好的解释。表格表示无法找到BadCOlumn,“延迟名称解析”适用于以后的使用。 – gbn 2009-08-29 08:32:17

0

这个问题也可见于下列情形:

IF 1 = 1 
    select dummy = GETDATE() into #tmp 
ELSE 
    select dummy = GETDATE() into #tmp 

虽然第二条语句永远不会执行发生同样的错误。 似乎查询引擎第一级验证忽略所有条件语句

0

你说你有后续请求的问题,那是因为对象已经退出。它建议您在完成后尽快放下临时表。

在阅读更多关于临时表的性能: SQL Server performance.com