为什么没有必要检查 Sybase 中的存储过程中是否存在#temp table
Why its not necesary to check if a #temp table exist inside a store procedure in Sybase
通常在构建临时文件之前 table(或 table)我会检查它是否存在:
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;
如果我不检查 table 是否存在并且我尝试创建一个 table 两次并使用一个已经存在的名称,我会收到一条错误消息
这里的问题是当我在一个过程中尝试代码时没有检查临时 table 是否存在。
我 运行 程序 2 次(所以第二次应该告诉我 table 已经存在)但它运行得很好
示例:
-- 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
有谁知道为什么?为什么我不需要检查过程中是否存在临时 table?
假设 Sybase ASE ...您在给定的 nesting/scope 级别只能有一个 #temp table(给定的名称)。
在连接级别(例如,isql
命令提示符),您处于 nesting/scope 级别 0。您可以在此处创建 #temp table 的单个实例。
当您调用存储过程(或触发触发器)时,您会进入一个新的 nesting/scope 级别。您可以在每个新的 nesting/scope 级别创建另一个 #temp table 实例。
注意:请记住,当您退出存储过程时,会执行两个关键操作...1) proc 创建的任何#temp tables 都会自动删除,2) 您退出 proc 的nesting/scope级,即nesting/scope级减一
考虑以下示例:
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 名称的格式类似于:
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 table 名称(如系统所见)的唯一区别是 nesting/scope 级别,可以在名称的第 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
通常在构建临时文件之前 table(或 table)我会检查它是否存在:
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;
如果我不检查 table 是否存在并且我尝试创建一个 table 两次并使用一个已经存在的名称,我会收到一条错误消息
这里的问题是当我在一个过程中尝试代码时没有检查临时 table 是否存在。 我 运行 程序 2 次(所以第二次应该告诉我 table 已经存在)但它运行得很好
示例:
-- 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
有谁知道为什么?为什么我不需要检查过程中是否存在临时 table?
假设 Sybase ASE ...您在给定的 nesting/scope 级别只能有一个 #temp table(给定的名称)。
在连接级别(例如,isql
命令提示符),您处于 nesting/scope 级别 0。您可以在此处创建 #temp table 的单个实例。
当您调用存储过程(或触发触发器)时,您会进入一个新的 nesting/scope 级别。您可以在每个新的 nesting/scope 级别创建另一个 #temp table 实例。
注意:请记住,当您退出存储过程时,会执行两个关键操作...1) proc 创建的任何#temp tables 都会自动删除,2) 您退出 proc 的nesting/scope级,即nesting/scope级减一
考虑以下示例:
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 名称的格式类似于:
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 table 名称(如系统所见)的唯一区别是 nesting/scope 级别,可以在名称的第 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