这种临时表应如何册除? (300分)

  • 主题发起人 主题发起人 Jiao_he
  • 开始时间 开始时间
J

Jiao_he

Unregistered / Unconfirmed
GUEST, unregistred user!
为什么用 Select * into #Temp from Table 语句生成的临时表就能用下面语句判断进行删除
if exists(select name from tempdb..sysobjects where name Like '#Temp%')
drop table #Temp

而用Exec('Select * into #Temp from Table') 语句生成的临时表则不能用上述语判断进行删除?
是否用Exec('Select * into #Temp from Table') 语句生成的临时表名已改名了?
那么应该怎样进行判断并删除?
 
好像执行完这句话后,临时表就已经删除了!
 
自已解决了。用Exec 生成的是全局临时表,所以不应只用一个#号,而应用##,而且判断时不应加%号
如下写就可以删除临时表了:
Exec(Select * into ##Temp from Table)
if exists(select name from tempdb..sysobjects where name Like '##Temp')
drop table ##Temp

反正我用上述语句解决了在存储过程中生成的临表时记录更新迟缓的问题。
但不知道理是否正确!
请大家多发表高见,否则我的300大分就浪费了。



 
不要生成全局临时表,这样多用户运行会报错的!!
 
如果你用的不是sql server的话,我就惨了,因为浪费了这么多唾沫[:(!]

一般临时表的形式应该是
#Temp_______________________________________________________________________________________________________________000000000023,
后面那个应该是连接的一个标识符.
方法一.用下面的语句试试看,我实验过了:
procedure TForm1.Button1Click(Sender: TObject);
begin
with adoquery1 do
begin
close;
sql.Clear;
sql.Add('Select * into #Temp from t1 ');
adoquery1.ExecSQL;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
strSQL : string;
begin
with adoquery1 do
begin
close;
sql.Clear;
strSQL := 'if exists(select name from tempdb..sysobjects where name Like '+QuotedStr('#Temp%')+') drop table #temp';
sql.Add(strSQL);
adoquery1.ExecSQL;
end;
end;

方法二. 如果没有多线程对数据库的操作,删除临时表的另一个方法就是
var
Con : TADOConnection;
procedure TForm1.Button1Click(Sender: TObject);
begin
CreateConn;
adoquery1.Connection := Con;
with adoquery1 do
begin
close;
sql.Clear;
sql.Add('Select * into #Temp from t1 ');
adoquery1.ExecSQL;
end;
if assigned(Con) then Freeandnil(Con);// 数据库系统会自动删除临时表
// 或者你可以将这句单词单独的过程
//作为删除临时表的用途.
end;

procedure TForm1.CreateConn;
begin
if Con = nil then
begin
Con := TADOConnection.Create(Self);
Con.ConnectionString := 'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=test;Data Source=syport';
Con.LoginPrompt := False;
Con.Connected := True;
end;
end;
但是这样的开销会比固定的一个Connection要大一些.

其实最简单的删除临时表的方法应该是
ADOConnection1.Connected := False;
但是由于涉及到数据库系统设置的断开连接时间问题,
所以不好要等一段时间系统才会自动删除临时表.
因为ADOConnection1.Connected := False;只是通知数据库
系统我断开了,但是真实的断开时间要看数据库的配置,我记得应该是
数据库的 Connection time-out参数设置的.
 
都罗嗦两句,如果你的系统是多用户的,千万不要用全局临时表,因为会有冲突.
jack.shi说的自动删除是指在存储过程中建立临时表,系统会自动删除,但是
如果用query生成的,除非断开了连接,系统是不会自动删除的.
 
我是用SQL Sever7.0 的.
我是在存储过程中运行上述相同结构语句。
你们先试试在Query Analyzer中运行下述语句,看看有何结果(注意一定要用Eexec来运行,因为实际程序中需要用到)
exec('select * into #Temp from Table1 select * from #Temp')
go
exec('select * into #Temp from Table2 select * from #Temp')
go
注意选两个Table1与Table2不同结构的表。
运行后就发现问题了,显示结果是:显示两个相同结构的表字段(是Table1的),但内容就是各自的。
即使你断开Query Analyzer再运行,结果一样(除非断开时间十几二十分钟以上)。

所以若要结果正常,必须在运行第一句exec语句后先把#Temp删除,但在存储过程中如何删除那个#Temp的表?
因为只用一个#的临时表无法判断出来,所以只好用##的(判断用我第二个留言的方法)。
请大家指教!

>>bluerain
你的语句是在Query中实现的,但在Query Analyzer中似乎是跟直接运行'Select * into #Temp from t1 ' 一样,如果是这样当然可以判断出来。
若在存储过程中又应怎样,请指教!
 
如果你是在存储过程中执行生成临时表的语句,上面我说的就大多是废话了.呵呵.
因为存储过程中的临时表当存储过程结束后,就自动释放了.

但是你用Exec('select * into #Temp from t1')这种语句在sql server中是有问题的.
因为动态sql语句的执行类似一个存储过程,所以再你执行完
Exec('select * into #Temp from t1')后,临时表就已经释放了.也就是说
Exec('select * into #Temp from t1')这句话你根本得不到临时表.

一般开始对#Temp结构不清楚,要用动态sql来调整字段的情况,一般的方法
是先显式的
Create table #temp(id int)
然后用动态sql去修改临时表的结构
exec('ALTER TABLE #temp ADD column_b VARCHAR(20) NULL')来实现.

不过这样来实现你的需求可能很比较麻烦,因为要动态去查t1等表的字段类型,更好的
方法我再想想.
 
如果在存储过程中生成的临时表会自动删除,但为什么运行完
Exec('select * into #Temp from t1')这句后,
再运行Exec('select * into #Temp from t2')时显示的表构仍是t1的表结构呢?这种情况应怎样避免?
(注意:t1与t2是不同表)
 
当你程序关闭了的话,#Temp 当然会删除除了
Exec('select * into #Temp from t1')这句后,
若没删除就
再运行Exec('select * into #Temp from t2')

应该是不能运行这句的了
 
学习!

收藏了!
 
Exec被SQL套进存储过程运行,结束后临时表自然就pp了.
 
我请们还是先试试吧:
Exec('select * into #Temp from t1' select * from #temp)
go
Exec('select * into #Temp from t2' select * from #temp)
go

即使删除了,但为什么显示的结果字段都是t1的?又如何决?

 
很奇怪,大家都只说存储过程运行后的临时表自然会删除。
好了,我也相信在存储过程中临时表是自动删除的,
但我想知道的是另一个问题,如我上述说的,为什么前后显示的结果会是第一个表字段结构呢?
那个问题究竟如何解决?因为就算临时表会自动删除,但显示有问题也不行呀?
真希望大家真的试试上述语句。我也重复了很多次了。

> 我请们还是先试试吧:
> Exec('select * into #Temp from t1' select * from #temp)
> go
> Exec('select * into #Temp from t2' select * from #temp)
> go
> 即使删除了,但为什么显示的结果字段都是t1的?又如何解决?

事实胜于雄辩!
 
反正没结果,分分了!
 
多人接受答案了。
 
后退
顶部