访问未声明的变量



为什么此代码使用NULL值而不是错误消息Must declare the scalar variable "@i".给出一行。为什么微软在T-SQL中使用了此行为?

if 1 = 0
begin
    declare @i int = 1;
end;
select @i;

来自msdn:

变量的范围是Transact-SQL语句的范围 可以引用变量。变量的范围从 指点它被声明为直到批处理结束或存储过程 它被声明。

因此,在您的示例中,@i变量的范围是批处理或过程定义了它们。

所以下一个查询: -

if 1 = 0
begin
    declare @i int = 1
end
else
begin
    declare @i int = 3
end
select @i

正在检索下一个错误: -

已声明了变量名称'@i'。可变名称必须 在查询批次或存储过程中保持独特。

但是您的查询没有。

update

Microsoft表示他们不会解决此问题: -

使声明仅在块中可见的变量。

DECLARE s范围是当前批处理,而不是代码块。因此,编译器可以看到您的变量。

问题是 - 如果可见,为什么不分配。作业与常规评估相同,只是在可变声明中以在线书面。分配是受代码流影响的命令。这是您的代码的实际执行计划:

<Batch>
  <Statements>
    <StmtCond StatementCompId="1" StatementId="1" StatementText="&#xD;&#xA;if 1 = 0&#xD;" StatementType="COND" RetrievedFromCache="false">
      <Condition />
      <Then>
        <Statements>
          <StmtSimple StatementCompId="2" StatementId="2" StatementText="&#xA;begin&#xD;&#xA;    declare @i int = 1;&#xD;" StatementType="ASSIGN" RetrievedFromCache="false" />
        </Statements>
      </Then>
    </StmtCond>
  </Statements>
  <Statements>
    <StmtSimple StatementCompId="4" StatementId="3" StatementText="&#xA;end;&#xD;&#xA;&#xD;&#xA;select @i;&#xD;&#xA;" StatementType="SELECT WITHOUT QUERY" RetrievedFromCache="false" />
  </Statements>
</Batch>

及以下是扩展声明和作业的计划:

declare @i int 
if 1 = 0
begin
    set @i = 1;
end;
select @i;
<Batch>
  <Statements>
    <StmtCond StatementCompId="1" StatementId="1" StatementText="declare @i int &#xD;&#xA;&#xD;&#xA;if 1 = 0&#xD;" StatementType="COND" RetrievedFromCache="false">
      <Condition />
      <Then>
        <Statements>
          <StmtSimple StatementCompId="2" StatementId="2" StatementText="&#xA;begin&#xD;&#xA;    set @i = 1;&#xD;" StatementType="ASSIGN" RetrievedFromCache="false" />
        </Statements>
      </Then>
    </StmtCond>
  </Statements>
  <Statements>
    <StmtSimple StatementCompId="4" StatementId="3" StatementText="&#xA;end;&#xD;&#xA;&#xD;&#xA;select @i;&#xD;&#xA;" StatementType="SELECT WITHOUT QUERY" RetrievedFromCache="false" />
  </Statements>
</Batch>

最新更新