1. 程式人生 > >各種資料庫臨時表的使用區別總結

各種資料庫臨時表的使用區別總結

[size=large]雖然SQL92, 99, 2003, 2008標準都有推出,但並不是所有商家嚴格按照標準行事。痛苦的是使用和應用不同資料庫的DBA和開發人員。
這裡以幾種主流資料庫為例,分別介紹一下臨時表的使用:

1. PostgreSQL (以9.x為例)

使用的是比較標準的語法:
create [global | local] temp table t ( id int primary key) on commit delete | preserve rows
其中,global和local是擺設,一樣的效果。都是會話級別的。當前會話退出,表即刪除。
可以建立與當前模式相同的表名,即可以建立同名的表t,drop table t時,會先刪除臨時表。如下例所示:

iihero=# create global temp table t(id int primary key) on commit delete rows;  
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pkey" for table "t"
CREATE TABLE
iihero=# insert into t values(1);
INSERT 0 1

iihero=# select * from t;
id
----
(0 rows)
</span>

iihero=# begin;
BEGIN
iihero=# insert into t values(1);
INSERT 0 1
iihero=# select * from t;
id
----
1
(1 row)

iihero=# commit;
COMMIT
iihero=# select * from t;
id
----
(0 rows)
</span>


2. DB2 9.x
1). DB2的臨時表需要用命令Declare Temporary Table來建立, 並且需要建立在使用者臨時表空間上;
2). DB2在資料庫建立時, 預設並不建立使用者臨時表空間, 如果需要使用臨時表, 則需要使用者在建立臨時表之前建立使用者臨時表空間;
3). 臨時表的模式為SESSION,SESSION即基於會話的,且在會話之間是隔離的。當會話結束時,臨時表的資料被刪除,臨時表被隱式卸下。對臨時表的定義不會在SYSCAT.TABLES中出現 .;
4). 預設情況下, 在Commit命令執行時, DB2臨時表中的所有記錄將被刪除; 這可以通過建立臨時表時指定不同的引數來控制;
5). 執行ROLLBACK命令時, 使用者臨時表將被刪除;
下面是DB2臨時表定義的一個示例:
DECLARE GLOBAL TEMPORARY TABLE results
(
RECID VARCHAR(32) , --id
XXLY VARCHAR(100), --資訊來源
LXDH VARCHAR(32 ), --資訊來源聯絡電話
FKRQ DATE --反饋時間
) ON COMMIT PRESERVE ROWS WITH REPLACE NOT LOGGED;


3. MySQL 5.X

基本上就是會話級的,與PG類似,但沒有PG語法完整。

建臨時表很容易,給正常的CREATE TABLE語句加上TEMPORARY關鍵字:
CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
value INTEGER NOT NULL
)
臨時表將在你連線MySQL期間存在。當你斷開時,MySQL將自動刪除表並釋放所用的空間。當然你可以在仍然連線的時候刪除表並釋放空間。
DROP TABLE tmp_table
如果在你建立名為tmp_table臨時表時名為tmp_table的表在資料庫中已經存在,臨時表將有必要遮蔽(隱藏)非臨時表tmp_table。
如果你宣告臨時表是一個HEAP表,MySQL也允許你指定在記憶體中建立它:
 CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
value INTEGER NOT NULL
) TYPE = HEAP
因為HEAP表儲存在記憶體中,你對它執行的查詢可能比磁碟上的臨時錶快些。然而,HEAP表與一般的表有些不同,且有自身的限制。

4. Sybase ASE15.X

基本上就是比較裸露的語法了:
create table tempdb..t(id int primary key), 這個等價於global temp table t, server級的, 各連線都可以訪問,需要顯式的drop
create table #t(id int primary key), 這個等價於local temp table t, 會話級的,連線斷開時會自動刪除

5. MS SQL Server 200X
與Sybase類似,但多出一個變種
create table ##t(id int primary key), 這個等價於global temp table t, server級的, 各連線都可以訪問,需要顯式的drop
create table #t(id int primary key), 這個等價於local temp table t, 會話級的,連線斷開時會自動刪除

最後,Sybase ASE以及MS SQL Server使用中,需要注意會話的自動產生及斷開
比如一個變數:

declare @vsql varchar(4096)
set @vsql="select * into #t123 from emp"
execute (@vsql)
set @vsql="select top 3 * from #t123"
execute (@vsql)
當你執行這個段時,你會發現,最後提示#t123不存在,因為execute在執行完時,會話即退出。要想執行成功,有兩種方法:
1. 將兩個sql合成一段來執行 : set @vsql = @vsql || " select top 3 * from #t123"
2. 使用global temp table, 即tempdb..t123或者SQLServer中的##t123

臨時表,在ASE, SQLServer中使用頻率非常高,經常出現在儲存過程當中。

6. Oracle9.x and later
語法與PG一樣,還提供on commit preserve rows, 和on commit delete rows功能。
但是隻提供global功能,意即表本身不會自動刪除。 只是提供是否保留資料的功能。這樣,preserve rows相當於會話級,而on commit delete rows則相當於事務級的臨時表了。用處還是蠻大的。
缺點還有:
1)不支援lob物件,這也許是設計者基於執行效率的考慮,但實際應用中確實需要此功能時就無法使用臨時表了。
2)不支援主外來鍵關係

總之,臨時表的實現和使用,還真沒有一個十全十美的商家。多留心一點就是了。[/size]