为什么不必检查Sybase中的存储过程中是否存在#temp表

时间:2017-11-01 15:31:50

标签: stored-procedures sybase-iq

通常在构建临时表(或表)之前,我会检查它是否存在:

  if not exists
   (select 1 from systable key join syscolumn key join  sysuser where lower(table_name) = '#mytable')
  then
  create table #mytable
    ( id bigint null)
  end if;

如果我不检查表是否存在,并且我尝试使用已存在的名称创建一个表两次,我会发现错误信息

这里的问题是当我在程序中尝试代码而不检查临时表是否存在时。 我运行了2次这样的程序(所以第二次应该告诉我表已经存在)但是它完美地运行了

示例:

 -- first time 
  create table #mytable
    ( id bigint null);   --  ok 
   -- second time 
  create table #mytable
    ( id bigint null);   --  error table already exist  
 --Proc
 create procedure user.create_temp_table  ()
  begin
   create table #mytable
    ( id bigint null);
  end ;
  create_temp_table  -- ok 
  create_temp_table  -- ok 

有谁知道为什么?为什么我不需要检查过程中是否存在临时表?

1 个答案:

答案 0 :(得分:2)

假设Sybase ASE ...在给定的嵌套/范围级别上只能有一个#temp表(给定名称)。

在连接级别(例如,isql命令提示符),您处于嵌套/范围级别0.您可以在此处创建#temp表的单个实例。

当您调用存储过程(或触发触发器)时,您将进入新的嵌套/范围级别。您可以在每个新的嵌套/范围级别创建#temp表的另一个实例。

注意:请记住,当您退出存储过程时,将执行两个键操作... 1)由proc创建的任何#temp表都会自动删除; 2)您退出proc的嵌套/范围级别,即,嵌套/范围级别减1。

考虑以下示例:

create proc child_proc
as
create table #t1(a int, b int)
select 'child_proc',name from tempdb..sysobjects where name like '#t1%' order by name
go

create proc parent_proc
as
create table #t1(a int, b int)
select 'parent_proc',name from tempdb..sysobjects where name like '#t1%' order by name
exec child_proc
go

create table #t1(a int, b int)
select 'top_level',name from tempdb..sysobjects where name like '#t1%' order by name
exec parent_proc
go

             name                 
 ----------  --------------------
 top_level   #t100000140011582650  -- command prompt

             name                 
 ----------  --------------------
 parent_proc #t100000140011582650  -- command prompt
 parent_proc #t101000140011582650  -- parent_proc

            name                 
 ---------- --------------------
 child_proc #t100000140011582650   -- command prompt
 child_proc #t101000140011582650   -- parent_proc
 child_proc #t102000140011582650   -- child_proc

临时表名称的格式如下所示:

table-name + 17-byte suffix consisting of:    

     2-digit (0-padded) nesting/scope level
     5-digit (0-padded) spid
    10-digit (0-padded) number

对于上面的例子,我的spid = 14;实际#temp表名称(系统可见)的唯一区别是嵌套/范围级别,可以在名称的第4 /第5位看到:

#t1 00 00014 0011582650  -- command prompt; nesting/scope level 0
#t1 01 00014 0011582650  -- parent_proc;    nesting/scope level 1
#t1 02 00014 0011582650  -- child_proc;     nesting/scope level 2