如果我调用一个递归调用自身的存储过程,我想知道@vars,#tables和##表是否有非冲突的实例副本。我猜测 @vars和#tables是好的,但##应该会产生问题。
我认为这个问题进一步扩展为:当sp自己调用时,是否会创建一个新会话?
答案 0 :(得分:2)
不,它没有。变量的范围限定为一个级别(因此它们对嵌套调用不可见),#temp表的作用域为会话,## temp表的作用域为全局。在T-SQL中甚至无法创建新会话(即使EXEC
创建新批处理,也不创建新会话)。好吧,你可以动态创建一个预定的工作(或者可以使用本地服务器OPENROWSET
),但这是作弊。
要小心在嵌套的存储过程中创建临时表:如果你不小心,你会遇到麻烦。具体而言,per the docs:
在存储过程或触发器中创建的本地临时表 可以与之前创建的临时表具有相同的名称 调用存储过程或触发器。但是,如果是查询 引用临时表和两个具有相同的临时表 在那时存在名称,没有定义查询是哪个表 解决了。嵌套存储过程也可以创建临时存储 与由。创建的临时表同名的表 调用它的存储过程。但是,要解决修改 对于在嵌套过程中创建的表,该表必须 具有与表相同的结构,具有相同的列名 在调用过程中创建。
这意味着“明显”的情况是,您在嵌套的每个步骤中创建“相同”的临时表,如您所期望的那样:每个嵌套调用都有其“自己的”表,并且不会看到父表。但是,如果不在嵌套调用中创建表,您将获得父表,如果您创建具有不同结构的表(无论出于何种原因),您实际上可以获得编译SQL Server检测到这种奇怪的情况时出错。
因此,您可以使用临时表作为保持调用状态的方式,或者特别是不通过“重新创建”它来执行此操作,但是由您来保持理智。
答案 1 :(得分:1)
简单来说
所以