初识临时表
臨時表就是那些名稱以井號 (#) 開頭的表。如果當(dāng)用戶斷開連接時沒有除去臨時表,SQL Server 將自動除去臨時表。臨時表不存儲在當(dāng)前數(shù)據(jù)庫內(nèi),而是存儲在系統(tǒng)數(shù)據(jù)庫 tempdb 內(nèi)。?
創(chuàng)建臨時表有多種方法。其一,先創(chuàng)建表結(jié)構(gòu),跟創(chuàng)建普通表一樣,只是表名多了個#號
create table #tmp ( id int, name varchar(50) )?有了表結(jié)構(gòu)就可以給表添加數(shù)據(jù),添加數(shù)據(jù)的方法,同普通表一樣。
其二,創(chuàng)建表同時插入數(shù)據(jù)?
select * int #tmp from table_Name //table_Name 為數(shù)據(jù)庫中的普通表,在創(chuàng)建#tmp的時候自動將table_Name 中的數(shù)據(jù)填充到#tmp臨時表中既然創(chuàng)建了表,我們就會聯(lián)想到怎么刪除表……同樣有兩種途徑。其一,手動刪除(drop table #tmp)。其二,當(dāng)連接斷開時,系統(tǒng)自動清除臨時表。
臨時表又可以分為兩類:本地和全局。如果創(chuàng)建了 employees 表,則任何在數(shù)據(jù)庫中有使用該表的安全權(quán)限的用戶都可以使用該表,除非已將其刪除。如果數(shù)據(jù)庫會話創(chuàng)建了本地臨時表 #employees,則僅會話可以使用該表,會話斷開連接后就將該表刪除。如果創(chuàng)建了 ##employees 全局臨時表,則數(shù)據(jù)庫中的任何用戶均可使用該表。如果該表在您創(chuàng)建后沒有其他用戶使用,則當(dāng)您斷開連接時該表刪除。如果您創(chuàng)建該表后另一個用戶在使用該 表,則 SQL Server 將在您斷開連接并且所有其他會話不再使用該表時將其刪除。
1、局部臨時表(#開頭)只對當(dāng)前連接有效,當(dāng)前連接斷開時自動刪除。???
2、全局臨時表(##開頭)對其它連接也有效,在當(dāng)前連接和其他訪問過它的連接都斷開時自動刪除。???
3、不管局部臨時表還是全局臨時表,只要連接有訪問權(quán)限,都可以用drop table #Tmp(或者drop table ##Tmp)來顯式刪除臨時表。 ?
當(dāng)創(chuàng)建本地或全局臨時表時,CREATE TABLE 語法支持除 FOREIGN KEY 約束以外的其它所有約束定義。如果在臨時表中指定 FOREIGN KEY 約束,該語句將返回警告信息,指出此約束已被忽略,表仍會創(chuàng)建,但不具有 FOREIGN KEY 約束。在 FOREIGN KEY 約束中不能引用臨時表。
考慮使用表變量而不使用臨時表。當(dāng)需要在臨時表上顯式地創(chuàng)建索引時,或多個存儲過程或函數(shù)需要使用表值時,臨時表很有用。通常,表變量提供更有效的查詢處理。
?
在此,我用臨時表做過的例子就是防止用戶重復(fù)登錄
????? 在我們開發(fā)商務(wù)軟件的時候,常常會遇到這樣的一個問題:怎樣防止用戶重復(fù)登錄我們的系統(tǒng)?特別是對于銀行或是財(cái)務(wù)部門,更是要限制用戶以其工號身份多次登入。
可能會有人說在用戶信息表中加一字段判斷用戶工號登錄的狀態(tài),登錄后寫1,退出時寫0,且登錄時判斷其標(biāo)志位是否為1,如是則不讓該用戶工號登錄。但是這樣那勢必會帶來新的問題:如發(fā)生象斷電之類不可預(yù)知的現(xiàn)象,系統(tǒng)是非正常退出,無法將標(biāo)志位置為0,那么下次以該用戶工號登錄則不可登入.
create procedure gp_findtemptable /* 尋找以操作員工號命名的全局臨時表 * 如無則將out參數(shù)置為0并創(chuàng)建該表,如有則將out參數(shù)置為1 * 在connection斷開連接后,全局臨時表會被SQL Server自動回收 * 如發(fā)生斷電之類的意外,全局臨時表雖然還存在于tempdb中,但是已經(jīng)失去活性 * 用object_id函數(shù)去判斷時會認(rèn)為其不存在.*/@v_userid varchar(6), -- 操作員工號@i_out int out -- 輸出參數(shù) 0:沒有登錄 1:已經(jīng)登錄asdeclare @v_sql varchar(100)if object_id('tempdb.dbo.##'+@v_userid) is nullbeginset @v_sql = 'create table ##'+@v_userid+'(userid varchar(6))'exec (@v_sql)set @i_out = 0endelseset @i_out = 1
? 在這個過程中,我們看到如果以用戶工號命名的全局臨時表不存在時過程會去創(chuàng)建一張并把out參數(shù)置為0,如果已經(jīng)存在則將out參數(shù)置為1。
?
上面還涉及到一個OBJECT_ID ()函數(shù):
?
Syntax:
OBJECT_ID ( '[ database_name . [ schema_name ] .?| schema_name .?object_name'?[ ,'object_type' ] )一般語法:int object_id('objectname');
此方法返回?cái)?shù)據(jù)庫對象標(biāo)識號。
其中,參數(shù)objectname 表示要使用的對象,其數(shù)據(jù)類型為nchar或char(如果為char,系統(tǒng)將其轉(zhuǎn)換為nchar)
object_type:為可選參數(shù),其數(shù)據(jù)類型為nchar或char(如果為char,系統(tǒng)將其轉(zhuǎn)換為nchar),指明架構(gòu)范圍的對象類型(object_name為字符串通過它,可以說明這個字符串究竟是說明對象,其列表見文章結(jié)尾)
?
ps:使用?OBJECT_ID?不能查詢非架構(gòu)范圍內(nèi)的對象(如?DDL?觸發(fā)器)。對于在?sys.objects?目錄視圖中找不到的對象,需要通過查詢適當(dāng)?shù)哪夸浺晥D來獲取該對象的標(biāo)識號。例如,若要返回?DDL?觸發(fā)器的對象標(biāo)識號,請使用?SELECT OBJECT_ID FROM sys.triggers WHERE name = 'DatabaseTriggerLog'。
?
返回類型為int,表示該對象在系統(tǒng)中的編號,如果找不到或發(fā)生錯誤一律返回NULL。
?
例子:
A.返回?cái)?shù)據(jù)庫AdventureWorks中Production.WorkOrder表的標(biāo)識號
?
USEmaster;GO
SELECTOBJECT_ID(N'AdventureWorks.Production.WorkOrder')?AS'Object?ID';
GO
?
B.存在性檢查
下列會確認(rèn)資料表有物件的標(biāo)識碼,藉此檢查指定的資料表是否存在。如果存在就刪除。
USEAdventureWorks;GO
IFOBJECT_ID(N'dbo.AWBuildVersion',?N'U')?ISNOTNULL
DROPTABLEdbo.AWBuildVersion;
GO
此方法一般用來判斷數(shù)據(jù)庫中本來用沒有此對象(procedures,views,functions等).
注意:
當(dāng)該參數(shù)對系統(tǒng)函數(shù)可選時,則系統(tǒng)采用當(dāng)前數(shù)據(jù)庫、主機(jī)、服務(wù)器用戶或數(shù)據(jù)庫用戶。內(nèi)置函數(shù)后面必須跟圓括號。?
如果指定一個臨時表名,除非當(dāng)前數(shù)據(jù)庫為tempdb(廢話),否則必須在臨時表名前面加上數(shù)據(jù)庫名,例如:?
SELECT OBJECT_ID('tempdb..#mytemptable')
?
?
Object_Type列表:
?
?
?
?
| AF =?聚合函數(shù)?(CLR) |
| C = CHECK?約束 |
| D = DEFAULT(約束或獨(dú)立) |
| F = FOREIGN KEY?約束 |
| FN = SQL?標(biāo)量函數(shù) |
| FS =?程序集?(CLR)?標(biāo)量函數(shù) |
| FT =?程序集?(CLR)?表值函數(shù) |
| IF = SQL?內(nèi)聯(lián)表值函數(shù) |
| IT =?內(nèi)部表 |
| P = SQL?存儲過程 |
| PC =?程序集?(CLR)?存儲過程 |
| PG =?計(jì)劃指南 |
| PK = PRIMARY KEY?約束 |
| R =?規(guī)則(舊式,獨(dú)立) |
| RF =?復(fù)制篩選過程 |
| S =?系統(tǒng)基表 |
| SN =?同義詞 |
| SQ =?服務(wù)隊(duì)列 |
| TA =?程序集?(CLR) DML?觸發(fā)器 |
| TF = SQL?表值函數(shù) |
| TR = SQL DML?觸發(fā)器 |
| U =?表(用戶定義類型) |
| UQ = UNIQUE?約束 |
| V =?視圖 |
| X =?擴(kuò)展存儲過程 |
?
轉(zhuǎn)載于:https://www.cnblogs.com/xiangzhong/archive/2012/08/03/2621133.html
總結(jié)
- 上一篇: mysql存储引擎优化参数
- 下一篇: 免费商用字体有哪些