SQL Server存储过程中的意外递归调用

时间:2012-10-03 17:34:03

标签: sql sql-server sql-server-2008 ssms

我有一个表,如果没有特定的键,我必须插入数据。我决定编写一个存储过程来插入数据。我想做的是:

  1. 创建存储过程。
  2. 使用存储过程插入一堆行。
  3. 删除存储过程。
  4. 我想在一个脚本文件中完成所有这些操作,以便没有人知道存在过程存在。

    这就是我所拥有的:

    创建

    CREATE PROCEDURE My_Proc(@key varchar(10))
      AS
      BEGIN
      IF NOT EXISTS (SELECT * FROM [dbo].[My_Table] WHERE [key] = @key)
        INSERT INTO [dbo].[My_Table] (key, created, modified)
        VALUES (@key, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
      END
    

    插入

    EXECUTE My_Proc 99241
    GO
    EXECUTE My_Proc 99242
    GO
    EXECUTE My_Proc 99243
    GO
    

    下拉

    DROP PROCEDURE My_Proc
    

    现在我右键单击SQL Server Management Studio中的数据库,单击New Query并粘贴上面的查询。我得到以下输出:

    (1 row(s) affected)
    
    (1 row(s) affected)
    Msg 217, Level 16, State 1, Procedure My_Proc, Line 9
    Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).
    
    (1 row(s) affected)
    Msg 217, Level 16, State 1, Procedure My_Proc, Line 9
    Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).
    

    我无法弄清楚导致错误的原因。此外,当我在SSMS上突出显示特定的EXECUTE命令时,EXECUTE My_Proc 99241插入数据时没有任何错误。

3 个答案:

答案 0 :(得分:5)

创建程序后需要GO。我相信第一个“EXECUTE My_Proc 99241”作为程序的一部分被包含在内,因为缺少GO,所以基本上你有一个递归调用。

创建过程语句(以及函数和类似语句)将所有内容都带到批处理的末尾,这就是为什么它们必须跟随“GO”或文件的结尾。

答案 1 :(得分:1)

如果你有一个键列表,其中一些可能在表中,那么尝试类似:

insert into my_tableC(key, created, modified)
    select key, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
    from <list of keys query> k
    where k.key not in (select key from my_table)

如果您有列表但不在表格中,则可以将其创建为:

with toinsert as (
    select <keyval1> as key union all
    select <keyval2> union all
    select <keyval3> . . .
    select <keyvaln>
)
insert into my_tableC(key, created, modified)
    select key, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
    from toinsert k
    where k.key not in (select key from my_table)    

答案 2 :(得分:0)

您插入的桌子上是否有触发器?因为您正在插入的表似乎存在某种循环。正在破坏的函数/过程的名称不是您创建的过程的名称。注意错误信息:

(1 row(s) affected)

(1 row(s) affected)
Msg 217, Level 16, State 1, Procedure InsertProfessionalComponentLookupForCpt, Line 9
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).

(1 row(s) affected)
Msg 217, Level 16, State 1, Procedure InsertProfessionalComponentLookupForCpt, Line 9
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).

确保没有任何触发器或Computed列在此表上做一些额外的工作。