选择“使用非无效列进行失败”

时间:2009-08-29 05:35:23

标签: sql sql-server sql-server-2005 tsql select

使用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,但我不喜欢这两种解决方案。

由于

4 个答案:

答案 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