TSQL 何时为存储过程中的变量(和表变量)分配内存

Posted

技术标签:

【中文标题】TSQL 何时为存储过程中的变量(和表变量)分配内存【英文标题】:TSQL when is memory allocated for variables (and table variables) in a stored procedure 【发布时间】:2016-01-04 14:23:59 【问题描述】:

我想知道如果我在 if 语句下声明变量和表变量是否会引发错误,是否会有所不同。因此,如果作为参数给出的@key 无效,则 sp 会抛出错误并且在没有为变量分配内存的情况下完成,或者它是否仍然分配内存?

create procedure dbo.FooSelect
    @key uniqueidentifier
as
begin
    set nocount on

    declare @count bigint

    declare @temp table (   FooID       bigint,
                            Name        nvarchar(100)
                            primary key (FooID))

    if not exists ( select 1
                    from dbo.Foo f
                    where f.Key = @key)
    begin
        ;throw 50000, 'Invalid key, permission denied!', 1
    end

    --#####################################################################
    -- declare better here (below the possible error) so in case of an error no memory is allocated?
    --#####################################################################

    select @count = count(*)
    from dbo.Foo

    if @count > 10
    begin
        insert into @temp (FooID, Name)
        select 
        from dbo.Foo f
        where f.Key = @key
              and f.FooID > 100
    end
    else
    begin
        insert into @temp (FooID, Name)
        select 
        from dbo.Foo f
        where f.Key = @key
              and f.FooID < 100
    end

    select *
    from @temp

    return 1
end

感谢您的帮助

【问题讨论】:

【参考方案1】:

这是一个带有一些代码的注释。

@ThomasAdelbauer TSQL 脚本中的变量在解析时被“确认”,而不是像在命令式语言中那样在运行时被“确认”。内存分配也是按需分配的。

也就是说在块内声明没有区别。 下面的例子有效。

if (1=2)
begin

  declare @variable int
  print 'never printed'

end

set @variable = 3

select @variable
GO

现在,如果您尝试在 DECLARE 行之前使用该变量,您将收到错误。

【讨论】:

【参考方案2】:

鉴于表变量在创建时为空,只有在您向其中插入一些行时才会真正开始使用内存。

在那之前它只是一些列定义。

换句话说,大部分内存使用将在 IF 语句之后分配,因此很难想象会产生显着差异的场景。

【讨论】:

感谢您提供的信息 - 无法找到明确的答案

以上是关于TSQL 何时为存储过程中的变量(和表变量)分配内存的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 PL/SQL 过程和表名作为变量打印动态 SQL 中的所有表行?

2017-3-16 Tsql基础编程 存储过程 触发器 级联删除

从子查询存储过程分配变量

函数内的局部变量何时*实际*被分配

何时为变量分配内存,在声明时还是在初始化时?

何时在声明或初始化时为变量分配内存?