使用#temp表时未检测到无效列

时间:2019-07-02 07:08:50

标签: sql-server tsql

示例:

create table dbo.t1 (id int)
if OBJECT_ID('dbo.s_Test') is not null drop proc dbo.s_Test 
GO
create proc dbo.s_Test 
as
    create table #t2 (id2 int)
    select t.id, t.xyz from dbo.t1 t join #t2 t2 on t2.id2 = t.id
GO

在创建proc s_Test时,我期望出现类似“无效的列名'xyz'的错误,但是在proc创建时没有错误。看来#temp表似乎与它有关,因为如果我使用表变量创建此版本:

if OBJECT_ID('dbo.s_Test2') is not null drop proc dbo.s_Test2 
GO
create proc dbo.s_Test2 
as
    declare @t2 table (id2 int)    
    select t.id, t.xyz from dbo.t1 t join @t2 t2 on t2.id2 = t.id
GO

我得到错误:无效的列名'xyz'。关于为什么#temp表版本在存储的proc创建时没有引发错误的任何想法? 万一重要,请使用SQL Server 2012。

1 个答案:

答案 0 :(得分:4)

这与延迟的名称解析和编译有关。此处更多信息:https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms190686(v=sql.105)

在编译时,临时表/变量不存在,因此不会编译该语句。它将在执行时引发错误。我知道,很糟糕。

如果您先运行带有表变量的语句,而之前没有 dbo.t1 之前先创建,则它也不会引发错误。