網(wǎng)站首頁 編程語言 正文
一、表變量
表變量在SQL Server 2000中首次被引入。
表變量的具體定義包括列定義,列名,數(shù)據(jù)類型和約束。而在表變量中可以使用的約束包括主鍵約束,唯一約束,NULL約束和CHECK約束(外鍵約束不能在表變量中使用)。
定義表變量的語句是和正常使用Create Table定義表語句的子集。只是表變量通過DECLARE @local_variable語句進(jìn)行定義。
1、定義和使用表變量
定義一個(gè)表變量,插入一條數(shù)據(jù),然后查詢:
DECLARE @tb1 Table
(
Id int,
Name varchar(20),
Age int
)
INSERT INTO @tb1 VALUES(1,'劉備',22)
SELECT * FROM @tb1
輸出結(jié)果如下:
2、表變量不能做如下事情:
來試試一些不符合要求的情況,例如添加表變量后,添加約束,并對約束命名:
ALTER TABLE @tb1 ADD CONSTRAINT CN_AccountAge
CHECK
(Account_Age > 18); -- 插入年齡必須大于18
SQL Server提示錯(cuò)誤如下:
SQL Server不支持定義表變量時(shí)對Constraint命名,也不支持定義表變量后,對其建Constraint。
更多的不允許,請查看下面的要求。
- 雖然表變量是一個(gè)變量,但是其不能賦值給另一個(gè)變量。
- check約束,默認(rèn)值和計(jì)算列不能引用自定義函數(shù)。
- 不能為約束命名。
- 不能Truncate表變量。
- 不能向標(biāo)識(shí)列中插入顯式值(也就是說表變量不支持SET IDENTITY_INSERT ON)
3、表變量的特征:
- 表變量擁有特定作用域(在當(dāng)前批處理語句中,但不在任何當(dāng)前批處理語句調(diào)用的存儲(chǔ)過程和函數(shù)中),表變量在批處理結(jié)束后自動(dòng)被清除。
- 表變量較臨時(shí)表產(chǎn)生更少的存儲(chǔ)過程重編譯。
- 針對表變量的事務(wù)僅僅在更新數(shù)據(jù)時(shí)生效,所以鎖和日志產(chǎn)生的數(shù)量會(huì)更少。
- 由于表變量的作用域如此之小,而且不屬于數(shù)據(jù)庫的持久部分,所以事務(wù)回滾不會(huì)影響表變量。
表變量可以在其作用域內(nèi)像正常的表一樣使用。更確切的說,表變量可以被當(dāng)成正常的表或者表表達(dá)式一樣在SELECT,DELETE,UPDATE,INSERT語句中使用,但是表變量不能在類似"SELECT select_list INTO table_variable"這樣的語句中使用。而在SQL Server2000中,表變量也不能用于INSERT INTO table_variable EXEC stored_procedure這樣的語句中。
二、臨時(shí)表
在深入臨時(shí)表之前,我們要了解一下會(huì)話(Session),一個(gè)會(huì)話僅僅是一個(gè)客戶端到數(shù)據(jù)引擎的連接。在SQL Server Management Studio中,每一個(gè)查詢窗口都會(huì)和數(shù)據(jù)庫引擎建立連接。
一個(gè)應(yīng)用程序可以和數(shù)據(jù)庫建立一個(gè)或多個(gè)連接,除此之外,應(yīng)用程序還可能建立連接后一直不釋放知道應(yīng)用程序結(jié)束,也可能使用完釋放連接需要時(shí)建立連接。
臨時(shí)表和Create Table語句創(chuàng)建的表有著相同的物理工程,但臨時(shí)表與正常的表不同之處有:
- 臨時(shí)表的名稱不能超過116個(gè)字符,這是由于數(shù)據(jù)庫引擎為了辨別不同會(huì)話建立不同的臨時(shí)表,所以會(huì)自動(dòng)在臨時(shí)表的名字后附加一串。
- 局部臨時(shí)表(以"#"開頭命名的)作用域僅僅在當(dāng)前的連接內(nèi),從在存儲(chǔ)過程中建立局部臨時(shí)表的角度來看,局部臨時(shí)表會(huì)在下列情況下被Drop:
a、顯示調(diào)用Drop Table語句
b、當(dāng)局部臨時(shí)表在存儲(chǔ)過程內(nèi)被創(chuàng)建時(shí),存儲(chǔ)過程結(jié)束也就意味著局部臨時(shí)表被Drop。
c、當(dāng)前會(huì)話結(jié)束,在會(huì)話內(nèi)創(chuàng)建的所有局部臨時(shí)表都會(huì)被Drop。 - 全局臨時(shí)表(以"##"開頭命名的)在所有的會(huì)話內(nèi)可見,所以在創(chuàng)建全局臨時(shí)表之前首先檢查其是否存在,否則如果已經(jīng)存在,你將會(huì)得到重復(fù)創(chuàng)建對象的錯(cuò)誤。
a、全局臨時(shí)表會(huì)在創(chuàng)建其的會(huì)話結(jié)束后被Drop,Drop后其他會(huì)話將不能對全局臨時(shí)表進(jìn)行引用。
b、引用是在語句級別進(jìn)行 - 不能對臨時(shí)表進(jìn)行分區(qū)。
- 不能對臨時(shí)表加外鍵約束。
- 臨時(shí)表內(nèi)列的數(shù)據(jù)類型不能定義成沒有在TempDb中沒有定義自定義數(shù)據(jù)類型(自定義數(shù)據(jù)類型是數(shù)據(jù)庫級別的對象,而臨時(shí)表屬于TempDb)。
由于TempDb在每次SQL Server重啟后會(huì)被自動(dòng)創(chuàng)建,所以你必須使用startup stored procedure來為TempDb創(chuàng)建自定義數(shù)據(jù)類型。你也可以通過修改Model數(shù)據(jù)庫來達(dá)到這一目標(biāo)。 - XML列不能定義成XML集合的形式,除非這個(gè)集合已經(jīng)在TempDb中定義。
臨時(shí)表既可以通過Create Table語句創(chuàng)建,也可以通過"SELECT <select_list> INTO #table"語句創(chuàng)建。你還可以針對臨時(shí)表用"INSERT INTO #table EXEC stored_procedure"這樣的語句。
臨時(shí)表可以擁有命名的約束和索引。但是,當(dāng)兩個(gè)用戶在同一時(shí)間調(diào)用同一存儲(chǔ)過程時(shí),將會(huì)產(chǎn)生”There is already an object named ‘<objectname>’ in the database”這樣的錯(cuò)誤。所以最好的做法是不用為建立的對象進(jìn)行命名,而使用系統(tǒng)分配的在TempDb中唯一的。
1、全局臨時(shí)表引用是在語句級別進(jìn)行
如:
1.新建查詢窗口,運(yùn)行語句:
CREATE TABLE ##temp(RowID int)
INSERT INTO ##temp VALUES(3)
2.再次新建一個(gè)查詢窗口,每5秒引用一次全局臨時(shí)表
While 1=1
BEGIN
SELECT * FROM ##temp
WAITFOR delay '00:00:05'
END
3.回到第一個(gè)窗口,關(guān)閉窗口。
4.下一次第二個(gè)窗口引用時(shí),將產(chǎn)生錯(cuò)誤。
三、比較
微軟推薦使用表變量,如果表中的行數(shù)非常小,則使用表變量。
臨時(shí)表和表變量有很多類似的地方。所以有時(shí)候并沒有具體的細(xì)則規(guī)定如何選擇哪一個(gè)。對任何特定的情況,你都需要考慮其各自優(yōu)缺點(diǎn)并做一些性能測試。
下面的表格會(huì)讓你比較其優(yōu)略有了更詳細(xì)的參考。
特性 | 表變量 | 臨時(shí)表 |
---|---|---|
作用域 | 當(dāng)前批處理 | 當(dāng)前會(huì)話,嵌套存儲(chǔ)過程, 全局:所有會(huì)話 |
使用場景 | 自定義函數(shù),存儲(chǔ)過程,批處理 | 自定義函數(shù),存儲(chǔ)過程,批處理 |
創(chuàng)建方式 | 只能通過DECLEARE語句創(chuàng)建 |
CREATE TABLE 語句 SELECT INTO 語句. |
表名長度 | 最多128字節(jié) | 最多116字節(jié) |
列類型 |
可以使用自定義數(shù)據(jù)類型 可以使用XML集合 |
自定義數(shù)據(jù)類型和XML集合必須在TempDb內(nèi)定義 |
Collation | 字符串排序規(guī)則繼承自當(dāng)前數(shù)據(jù)庫 | 字符串排序規(guī)則繼承自TempDb數(shù)據(jù)庫 |
索引 | 索引必須在表定義時(shí)建立 | 索引可以在表創(chuàng)建后建立 |
約束 | PRIMARY KEY, UNIQUE, NULL, CHECK約束可以使用,但必須在表建立時(shí)聲明 | PRIMARY KEY, UNIQUE, NULL, CHECK. 約束可以使用,可以在任何時(shí)后添加,但不能有外鍵約束 |
表建立后使用DDL (索引,列) | 不允許 | 允許. |
數(shù)據(jù)插入方式 | INSERT 語句 (SQL 2000: 不能使用INSERT/EXEC). |
INSERT 語句, 包括 INSERT/EXEC. SELECT INTO 語句. |
Insert explicit values into identity columns (SET IDENTITY_INSERT). | 不支持SET IDENTITY_INSERT語句 | 支持SET IDENTITY_INSERT語句 |
Truncate table | 不允許 | 允許 |
析構(gòu)方式 | 批處理結(jié)束后自動(dòng)析構(gòu) | 顯式調(diào)用 DROP TABLE 語句.? 當(dāng)前會(huì)話結(jié)束自動(dòng)析構(gòu) (全局臨時(shí)表: 還包括當(dāng)其它會(huì)話語句不在引用表.) |
事務(wù) | 只會(huì)在更新表的時(shí)候有事務(wù),持續(xù)時(shí)間比臨時(shí)表短 | 正常的事務(wù)長度,比表變量長 |
存儲(chǔ)過程重編譯 | 否 | 會(huì)導(dǎo)致重編譯 |
回滾 | 不會(huì)被回滾影響 | 會(huì)被回滾影響 |
統(tǒng)計(jì)數(shù)據(jù) | 不創(chuàng)建統(tǒng)計(jì)數(shù)據(jù),所以所有的估計(jì)行數(shù)都為1,所以生成執(zhí)行計(jì)劃會(huì)不精準(zhǔn) | 創(chuàng)建統(tǒng)計(jì)數(shù)據(jù),通過實(shí)際的行數(shù)生成執(zhí)行計(jì)劃。 |
作為參數(shù)傳入存儲(chǔ)過程 | 僅僅在SQL Server2008, 并且必須預(yù)定義 user-defined table type. | 不允許 |
顯式命名對象 (索引, 約束). | 不允許 | 允許,但是要注意多用戶的問題 |
動(dòng)態(tài)SQL | 必須在動(dòng)態(tài)SQL中定義表變量 | 可以在調(diào)用動(dòng)態(tài)SQL之前定義臨時(shí)表 |
原文鏈接:https://www.cnblogs.com/springsnow/p/9877458.html
相關(guān)推薦
- 2023-11-23 pyside6兩個(gè)按鈕,一個(gè)控制子線程的開始,暫停,。一個(gè)控制子線程結(jié)束
- 2022-05-31 如何使用正則表達(dá)式判斷郵箱(以C#為例)_C#教程
- 2022-09-14 iOS實(shí)現(xiàn)簡單長截圖_IOS
- 2022-06-02 關(guān)于docker?registry使用詳解_docker
- 2022-05-10 oracle如何創(chuàng)建或刪除臨時(shí)表空間和空間詳解
- 2022-10-23 Android?手寫RecyclerView實(shí)現(xiàn)列表加載_Android
- 2022-09-22 string類的模擬實(shí)現(xiàn)
- 2022-10-27 React事件處理和表單的綁定詳解_React
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支