T-SQL編程

来源:https://www.cnblogs.com/ruhaoren/archive/2020/04/27/12758965.html
-Advertisement-
Play Games

T-SQL(Transact-SQL)是一種 SQL 擴展語言,由微軟實現,運行在 Ms SQL Server 平臺上。T-SQL 主要用來和SQL Server 交流,而查詢語句則主要用來告訴伺服器該做什麼。T-SQL 是標準 SQL 語言的擴展,自然也繼承了其基本功能:DDL、DML,DCL,D... ...


    T-SQL(Transact-SQL)是一種 SQL 擴展語言,由微軟實現,運行在 Ms SQL Server 平臺上。T-SQL 主要用來和SQL Server 交流,而查詢語句則主要用來告訴伺服器該做什麼。T-SQL 是標準 SQL 語言的擴展,自然也繼承了其基本功能:DDL、DML,DCL,DQL。另外,T-SQL 擴展了標準 SQL 不具備的編程特性,比如:運算符、文本字元串處理、流程式控制制、存儲過程、API,自定義函數等。

 

  一  T-SQL是什麼

    T-SQL 並沒有被作為一種編程語言設計。雖然 T-SQL 經過多年的發展,已經加入了不少編程語言的特性,但其仍然缺少真正的編程語言所具備的能力和靈活性。

    T-SQL 被設計的目的是實現數據的檢索和操縱,雖然其具有一定的編程能力,但其性能不能被很好的得到保證,當你希望把 T-SQL 當做編程語言使用時,你會不可避免的遇到性能問題,所以,在使用它時,請在心裡牢記,T-SQL 是操縱數據集的,這才是它發揮真正作用的地方。

 

  二  編程特性

 

    1,語法約束

    T-SQL 命令不區分大小寫,但建議使用大寫。語句不強制使用 ; 結束。

1 SELECT * FROM TableName --可以運行
2 SELECT * FROM TableName;--也能運行

    註意縮進和對象命名規範。正確的縮進能保證你的代碼易於閱讀和維護。T-SQL 允許使用字母、數字、下劃線、@、#、$符號來創建你自己的標識符(如變數、表名、視圖名等),但首字母不能是數字和 $ 符號,建議遵循大駝峰命名法則。

1 CREATE TABLE MyTable
2 (
3     M_Name VARCAHR(20) NOT NULL,
4     ......
5 )

    T-SQL 同時支持雙引號和單引號,那麼如何區分呢?雙引號一般用來標識 T-SQL 對象,比如表、視圖,過程等,還有一種表示對象的方式是 [] ,而單引號用來表示字元串數據。

1 SELECT "M".*  FROM  "MyTable" AS "M"
2   WHERE "M".Name='張三';
3 SELECT "M".*  FROM  [MyTable];

    T-SQL 使用 -- 雙中橫線表示單行註釋,/* */ 表示多行註釋。

1 /* 
2 這是多行註釋
3 這是多行註釋
4  */
5 --這是單行註釋

      

    2,運算符

    數學運算符:+ 加、- 減、* 乘、/ 除、% 餘。數學運算符返回值時數學計算值。= 既可以是等號也可以是賦值。+ 既可以作為數學加號也可以作為連接運算符。

    比較運算符:> 大於、< 小於、>= 大於或等於、<= 小於或等於、<> 不等於、!= 不等於、!< 不小於、!> 不大於,比較運算返回的是布爾值。

    邏輯運算符:AND、OR、NOT、BETWEEN、LIKE、IN。

      

    3,變數

    變數分為局部變數和全局變數。局部變數用戶可以自定義,而全局變數由系統管理,用戶可以使用,但不能更改。 

    局部變數使用 DECLARE 關鍵字聲明,以 @ 符號標識。使用 SELECT 或 SET 關鍵之賦值。

1 DECLARE @Age INT
2 DECLARE @Name VARCAHR(20)
3 SET @Age=20
4 SELECT @Name='張三'
5 PRINT @Name+@Age

    SET 一次只能為一個變數賦值,SELECT 一次可以為多個變數賦值。在 T-SQL 中,有兩種方式輸出內容,PRINT 和 SELECT。PRINT 一次只能輸出一個值,通常用於向 API 返回值,而 SELECT 可以以數據集的形式返回多行記錄。

    全局變數以 @@ 符號標識,常用的全局變數如下:

1 SELECT @@version AS '版本';--返回當前資料庫的版本信息
2 SELECT @@error AS '錯誤ID';--返回上一次T-SQL的錯誤ID,如果正常執行了查詢,error為0,出錯時error一定大於0
3 SELECT @@identity AS '標示符';--返回最後一次的標識符,如先執行了
4 SELECT @@connections AS '連接次數';--返回自上次SQL啟動以來連接或試圖連接的次數
5 SELECT @@total_errors AS '錯誤總數';--返回至啟動以來的錯誤總數
6 SELECT @@total_read AS '讀取總數';--返回自啟動以來的讀取總數
7 SELECT @@total_write AS '寫入總數';--返回自啟動以來的寫入總數
8  ......

 

    4,流程式控制制

    BEGIN...END:該語句用來標記一個語句塊,通常和其他流程式控制制語句一起使用。

    IF...ELSE:條件判斷語句。如果 IF 關鍵字後面的條件表達式計算結果為真,則執行語句塊1,否者執行語句塊2。IF 和 ELSE 之間還可以存在 ELSE IF 組合關鍵字,表示邏輯上的其他情況。

1 IF 條件
2     BEGIN
3     語句塊1
4     END
5 ELSE
6     BEGIN
7     語句塊2
8     END    

    如果語句塊只有一條語句,那麼BEGIN...END 可以省略。

    WHILE:迴圈。當 WHILE 關鍵字後面的循壞條件為真時,執行下麵的語句塊,需要註意的是,語句塊中應該有能夠左右循壞條件的語句存在,否則這將變成一個死迴圈。

1 WHILE 迴圈條件
2 BEGIN
3     語句塊
4 END
5 --如果只有一條語句,也可以省略BEGIN...END

    BREAK 和 CONTINUE:退出迴圈。該關鍵字一般和迴圈配合使用,BREAK 用於結束整個迴圈,不管迴圈條件是否為真。CONTINUE 用於跳過本次迴圈需要執行的代碼快,直接開始執行下一次需要執行的代碼塊(前提是迴圈條件還為真)。

    WAITFOR:延時執行。

 1 BEGIN
 2     WAITFOR TIME '22:00'
 3     語句塊
 4 END
 5 --指定執行語句的具體時間
 6 BEGIN
 7     WAITFOR DELAY '01:00:00'
 8     語句塊
 9 END
10 --指定執行語句的延遲時間量

    CASE:基於列的計算返回指定的值。CASE 執行的邏輯和 IF ELSE 語句類似,當 WHEN 關鍵字後面的表達式結果為真時,用 THEN 後面的新值替換列中原來的值。

1 CASE2     WHEN 表達式 THEN 新的值或表達式
3 WHEN 表達式 THEN 新的值或表達式
4 ...... 5 ELSE 其他未指定匹配值或表達式的新值 6 END

 

    三  函數

 

    1,聚合函數

    聚合函數主要包括:SUM() 求和,AVG() 求平均值,MIN() 求最小值,MAX() 求最大值,COUNT() 計數。

    以上聚合函數和標準 SQL 中的聚合函數功能一樣,使用方式也一樣,這裡不再介紹,如有疑問可以參照我的《SQL入門》

      

    2,日期函數

    T-SQL 提供了功能強大的操作日期類型值的相關函數,通過這些函數你可以輕鬆實現比如,解析日期類型值的日期與時間部分,比較與操縱日期/時間值等。

    A:GETDATE() 和 GETUTCDATE()     

1 SELECT GETDATE() AS '標準時間'
2 SELECT GETUTCDATE() AS 'UTC時間'

    GETUTCDATE() 通過本地伺服器上的時區來求出 UTC 時間,一般使用前一個函數較多。

    B:DATEPART() 和 DATENAME()

    這兩個函數的作用類似,都是用於返回日期中指定的部分,不通點在於:DATEPART() 返回值類型為 INT,而DATENAME() 為 NVARCHAR。

 1 DECLARE @MyDate;
 2 SET @MyDate=GETDATE();
 3 PRINT DATEPART(year,@mydate);--int
 4 PRINT DATENAME(year,@mydate);--nvarcahr
 5 PRINT DATEPART(month,@mydate);--int
 6 PRINT DATENAME(month,@mydate);--nvarcahr
 7 PRINT DATEPART(day,@mydate);--int
 8 PRINT DATENAME(day,@mydate);--nvarcahr
 9 PRINT DATEPART(dayofyear,@mydate);--int
10 PRINT DATENAME(dayofyear,@mydate);--nvarcahr
11 --可選的參數還有 week,weekday,hour,minute,second,millisecond等,請自行測試返回值

    C:YEAR(),MONTH(),DAY()

    以 INT 類型值返回指定日期的年,月,日。

1 SELECT YEAR(MyDate)AS YEAR,MONTH(MyDate)AS MONTH,DAY(MyDate)AS DAY

    D:DATEADD() 和 DATEDIFF()

    DATEADD() 用於計算給定時間間隔後的日期,DATEDIFF() 用於計算兩個日期之間指定單位的時間差。

1 DECLARE @MyDate DATETIME;
2 DECLARE @DateAfter7Days DATETIME;
3 SET @MyDate=GETDATE();
4 SET @DateAfter7Days=DATEADD(day,7,@MyDate) ;--計算距今7天之後的日期
5 PRINT @DateAfter7Days;
6 PRINT DATEDIFF(day,@MyDate,@DateAfter7Days) ;--7,差7天
7 --第一個參數都是時間單位,可選的有:year,month,day,week,hour,minute,second等,DATEADD()的第二個參數是一個數字,可以為負,以為之前的日期

 

    3,數學函數

    T-SQL 數學函數專門用於數學計算,常用的數學函數列表請移步《T-SQL 數學函數》,這裡不舉例說明。

      

    4,字元函數

 1 SELECT ASCII('ABC');--計算字元串第一個字元的ASCII值
 2 SELECT CHAR(65);--把給定ASCII編碼轉換成字元
 3 
 4 SELECT LOWER('AbC');--全轉換為小寫
 5 SELECT UPPER('aBc');--全轉換為大寫
 6 
 7 SELECT LTRIM('   AAA');--去掉左邊的空格
 8 SELECT RTRIM('AAA   ');--去掉右邊的空格
 9 
10 SELECT LEN('  ABC  ');--計算字元個數,不包含後面的空格
11 SELECT LEFT('ABCDEFG',3);--從左邊返回指定個數的字元
12 SELECT RIGHT('ABCDEFG',3);--從右邊返回指定個數的字元
13 SELECT SUBSTRING('ABCDEFG',3,2);--從第三個字元開始返回2個字元
14 
15 SELECT CHARINDEX('A', 'CCBBAA'); --返回第一個參數字元串在指定字元串中的位置
16 SELECT REPLACE('AABBCC','A','D'); --用第三個參數替換第一個參數中的第二個參數所指定字元串

 

    5,類型轉換函數

    T-SQL 中的顯示類型轉換通過 CONVERT() 和 CAST() 實現。

1 SELECT CONVERT(INT,' 123 ');
2 SELECT CAST(' 123 ' AS INT);
3 --把字元串轉換成數字,可以有空格,但不能有其他字元
4 
5 SELECT CONVERT(DATE,'2020-01-01');
6 SELECT CAST('2020-01-01' AS DATE);
7 --把字元串表示的日期轉換為日期格式

    CONVERT() 另一個很重要的應用是:以不同的格式顯示日期。這是你需要傳入第三個參數,該參數用來指定格式日期:

1 SELECT CONVERT(VARCHAR(19),GETDATE());--04 27 2020 11:10AM
2 SELECT CONVERT(VARCHAR(10),GETDATE(),110); --04-27-2020
3 SELECT CONVERT(VARCHAR(11),GETDATE(),106);--27 04 2020
4 SELECT CONVERT(VARCHAR(24),GETDATE(),113);--27 04 2020 11:11:07:857

 

    6,排序

    ROW_NUMBER() OVER():通過在 OVER 中使用 ORDER BY 字句,對指定列排序,並生成一個標識該行的唯一序號(從1開始)。比如有如學生生源信息表 Person:

id name prov
1001 張一 四川
1002 張二 湖北
1003 張三 上海
1004 張四 北京
1005 張五 四川
1 SELECT ROW_NUMBER() OVER(ORDER BY ID) AS NUM,* FROM Person; --多了一列 NUM,值從1 - 4
1 SELECT ROW_NUMBER() OVER(PARTITION BY PROV ORDER BY ID) AS NUM,* FROM Person;
2 -- 先通過 prov 分組學生信息,然後再通過 id 對學生在組內排序,生成 num 列,張一的 num 為1,張五的 num 為 2,其他的均為1

    RANK() OVER():排序和 ROW_NUMBER() OVER() 相似,區別是它不能分組排序,並且它的排序結果可能會出現相同的序號,且整體可能會不連續。

    如果某些行的的值相同,那麼 RANK() OVER() 會為這些行給出相同的序號,並且,下一行的排序並不會和上一個相鄰。

    比如:前兩個學生的成績都是 100 分,那麼他們應該是併列第一名,排序都是 1,第三名學生的成績是 99,應該是第二名,但 RANK() OVER() 的排序會是 3 。

 

  四  編程對象

 

    1,視圖

    設計視圖的唯一目的就是簡化代碼,解決代碼重用問題。

    視圖是一個邏輯表,它和真正的表在使用上完全一致,但他不是一個真正的表,視圖的本質是一個複雜的查詢語句。查詢視圖會返回數據,但這些數據並不是存儲在視圖中。而是在具體的真實的表中。

    語法:

 1 CREATE VIEW VIEW_NAME
 2 AS
 3     語句
 4 --創建視圖
 5 ALTER VIEW VIEW_NAME
 6 AS
 7     語句
 8 --修改視圖
 9 DROP VIEW VIEW_NAME 
10 --刪除視圖

    創建視圖時可以在視圖名後使用()來為視圖的列指定新的名稱,但必須全部提供,不能只指定一部分列的新名稱。

    雖然視圖也可以用來對原始數據進行操作,但不建議這樣做,因為使用視圖簡化查詢才是它的本職工作。

    使用視圖的一個註意點:不能直接使用 order by,如果需要排序,則必須配合 TOP 關鍵字一起使用。

    

    2,存儲過程

    存儲過程不僅可以實現返回查詢數據集的功能,而且功能比視圖更進一步,它還提供了很多編程功能,比如:帶參數的視圖,返回標量值,維護記錄,處理業務邏輯等等。

    一個存儲過程實現了一個特定的功能,並且別SQL Server 編譯好後存儲在資料庫中,下一次執行不需要重新編譯,提高程式執行效率。

    先來看基本語法:

 1 CREATE PROCEDURE PROC_NAME
 2 AS
 3     語句
 4 --創建存儲過程
 5 ALTER PROCEDURE PROC_NAME
 6 AS
 7     語句
 8 --修改存儲過程
 9 DROP PROCDURE PROC_NAME
10 --刪除存儲過程
11 EXECUTE PROC_NAME
12 --執行存儲過程

    A:帶參數的存儲過程

1 CREATE PROCEDURE Proc_name
2 @Var_name
3 AS
4     SELECT *  FROM Table_name
5         WHERE Some_col = @Var_name 
6 --在存儲過程中,使用變數過濾數據,變數不需要使用 declare 關鍵字
7 EXECUTE Proc_name Something;
8 EXECUTE Proc_name @Var_name=Something;
9 --兩種傳參的方式,多個參數使用逗號隔開

    B:返回值

    從存儲過程返回值有兩種方式,OUTPUT 修飾符和 RETURN 關鍵字。

    先來看 OUTPUT 方式:

 1 CREATE PROCEDURE P_TEST
 2 @OUT INT OUTPUT
 3 AS
 4     SET @OUT=1;
 5 GO
 6 DECLARE @NUM INT;
 7 EXECUTE P_TEST @NUM OUTPUT;
 8 SELECT @NUM;
 9 GO
10 --GO 表示一批 T-SQL 語句結束,GO 之後的 T-SQL 語句屬於另一個批處理的範圍,GO 不是 T-SQL 命令,它只是一個能被 SQL Server 管理器識別的命令

    使用這種方式,在創建存儲過程時,需要定義一個帶有 OUTPUT 修飾符的參數,用於存儲即將被返回的值。在存儲過程的外部,也需要定義一個變數,用來接收返回的值。並且在執行存儲過程時,需要把接收值的變數傳遞到存儲過程中去,且必須指明修飾符 OUTPUT,否則,存儲過程雖然能正常執行,但不會返回任何數據。

    另一種 RETURN 方式:

1 ALTER PROCEDURE P_TEST
2 AS
3     RETURN 1;
4 GO
5 DECLARE @NUM INT;
6 EXECUTE @NUM = P_TEST;
7 SELECT @NUM;
8 GO

    這種方式使用 RETURN 關鍵字顯示的指定需要返回的值,但與 OUTPUT 不同的是,它只能返回 INT類型的值。這種方式使用起來更簡單,不許要定義額外的變數,只需要在外部定義一個接收數據的變數,併在執行時賦值,即可拿到存儲過程的返回值。

    RETURN 還有一個功能:結束存儲過程的執行。即執行完 RETURN 語句之後,後面的任何語句都不會再被執行了,存儲過程的執行到此結束。

    

    3,自定義函數

    和存儲過程很相似,用戶自定義函數也是一組有序的T-SQL語句,用戶自定義函數被預先優化和編譯並且作為一個單元進行調用。它和存儲過程的主要區別在於返回結果的方式。

    用戶自定義函數可以傳入參數,但傳出參數被返回值概念替代了。用戶自定義函數的返回值可以是普通的標量值,也可以是表。

1 CREATE FUNCTION FUN_NAME
2 ( 參數列表 )
3 RETURNS 數據類型
4 AS
5 BEGIN
6     語句塊
7 END

    使用 CREATE FUNCTION 創建用戶自定義函數,函數名後面用()定義傳入的參數,然後使用 RETURNS 定義函數返回值的數據類型,用戶自定義函數的語句塊必須包含在 BEGIN...END中,並且在自定義函數內部,不能調用非確定性的函數,比如 GETDATE()。這是因為如果在內部出現非確定性函數,可能導致自定義函數在參數相同的情況下而返回值不同。請看下麵的例子:

1 CREATE FUNCTION GetAge
2 (@Birthday DATE,@Today DATE)
3 AS
4 BEGIN
5     RETURN DATEDIFF(DAY,@Birthday,@Today)/365
6 END
7 --根據提供的生日和現在的日期,計算年齡
8 SELECT DBO.GetAge('2000-01-01',GETDATE());

    通常情況下,SQL SERVER 把沒指定所有者或模式的函數調用當做一個系統內置函數,所以在使用用戶自定義函數時,請至少要指定所有者或模式名。

    如果要使用用戶自定義函數返回表類型的值,你需要這樣做:

 1 CREATE FUNCTION MYFUN(@VAR 數據類型)
 2 RETURNS TABLE
 3 AS
 4 BEGIN
 5     RETURN
 6     (
 7         SELECT * FROM TABLENAME WHERE 使用@VAR 的條件表達式;
 8     )
 9 END
10 
11 SELECT * FROM MYFUN(參數值);

    使用 SELECT * FROM 函數名這樣的語法,那麼這個函數基本和表具有一樣的功能。

 

  五  其他

 

    1,游標

    游標本質上是一個包含多條記錄的結果集,保存在記憶體中。在 T-SQL 中,聲明一個游標類型的變數,你就可以對讀入的結果集進行管理,對每條記錄進行迭代了。所以,游標實際上是一種能從包括多條數據記錄的結果集中,每次提取一條記錄的機制。

    游標基本用法:

 1 --1:創建游標
 2 DECLARE Cur_Name CURSOR
 3 FOR
 4     SELECT Col1,Col2 FROM Tbale_name
 5 DECLARE @Var_Name1,@Var_Name2
 6 --2:打開游標
 7 OPEN Cur_Name
 8 --3:檢索與操作數據
 9 FETCH NEXT FROM Cur_Name INTO @Var _Name1,@Var_Name2
10 WHILE @@Fetch_Status=0
11 BEGIN
12     PRINT @Var _Name1+':'+@Var_Name2
13     FETCH NEXT FROM Cur_Name INTO @Var _Name1,@Var_Name2
14 END
15 --4:關閉游標
16 CLOSE Cur_Name
17 --5:釋放游標
18 DEALLOCATE Cur_Name

    使用游標必要的五步:創建,打開,檢索,關閉,釋放。缺一不可。

    創建游標時,游標名和關鍵字 CURSOR 之間可以有可參數列表:INSENSITIVE,SCROLL,前者表示生成一個結果集的副本,而不是使用資料庫的元數據。後者指定在數據檢索時,所有的提取選項(FIRST(第一條記錄)、LAST(最後一條記錄)、PRIOR(上一條記錄)、NEXT(下一條記錄)、RELATIVE(相對當前移動 n 行的記錄)、ABSOLUTE(第 n 記錄))均可用。一般到了使用游標的時候,都是需要對每一條數據進行不同的操作了,所以提取選項多數情況都是使用 NEXT。

    在查詢語句之後,還可以通過 FOR 關鍵字指定哪些列可更新或者只讀,語法規則:[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]

    游標的主要作用在於,允許程式對由查詢語句 SELECT 返回的行集合中的每一行執行相同或不同的操作,而不是對整個行集合執行同一個操作,並且它還提供對基於游標位置而對錶中數據進行刪除或更新的能力。

    使用游標雖然可以帶來一定程度的靈活性,但它是以犧牲性能和效率為代價的,所以游標一般作為最後的開發選項,畢竟,即使不對數據做任何特殊操作,也需要必要的五個步驟。

    

    2,觸發器

    觸發器實際上是一類特殊的存儲過程,它能被 DDL 和 DML 觸發,並自動運行,不能被用戶顯式的觸發。

    如果我們為表或視圖的某些操作設置觸發器後,那麼,當我們在資料庫中針對這些表或視圖執行這些操作時,觸發器內的程式代碼將被執行。

    基本語法(DML觸發器):

1 CREATE TRIGGER 觸發器名稱
2 ON 表或視圖
3 觸發器類型(FOR|AFTER|INSTEAD OF4 操作類型(INSERTUPDATEDELETE5 AS
6     語句塊

    基本語法(DDL觸發器):

1 CREATE TRIGGER 觸發器名稱
2 ONALL SERVER|DATEBASE)
3 觸發器類型(FOR|AFTER)
4 操作類型(CREATEALTERDROP...5 AS
6     語句塊

    觸發器類型 FOR 和 AFTER 都是指在操作成功後執行,區別是 AFTER 類型只支持表,而不支持視圖。

    INSTEAD OF 觸發器使用觸發器內部的操作替代指定的操作類型,真正起作用的是觸發器裡面的動作!

    

    3,其他的

    A:MERGE

    MERGE 命令的作用是根據與源表的聯接結果在目標表上運行插入,更新或刪除操作。比如,通過對比另一個表的差異,在一個表中插入、更新或刪除數據,以保證兩個表中的數據同步。

    一個簡單的示例:

 1 MERGE INTO Target
 2  --這裡是目標表,它將要被源表Merge
 3 USING Source
 4 --這裡是源表
 5 ON 匹配條件
 6     WHEN MATCHED
 7 --匹配條件為真的記錄,執行下麵的then
 8         THEN UPDATE --執行更新操作 
 9     WHEN NOT MATCHED BY TARGET
10 --目標表中不存在,而源表中存在數據,執行下麵的then
11         THEN INSERT--執行插入操作
12     WHEN NOT MATCHED BY SOURCE
13 --當目標表中存在,而源表中不存在數據執,執行下麵then
14         THEN DELETE--執行刪除操作

    MERGE 命令在許多時候都可以替代游標批量操作數據,下一次你在考慮使用游標時,不妨先想一想,能否用 MERGE 代替呢!

    B:臨時表和表變數

    臨時表與永久表相似,只是它的創建是在 Tempdb 中,它只有在一個資料庫連接結束後或者由SQL命令DROP掉,才會消失,否則就會一直存在。

    臨時表分為本地和全局兩種,本地臨時表的名稱都是以“#”為首碼,只有在本地當前的用戶連接中才是可見的,當用戶從實例斷開連接時被刪除。全局臨時表的名稱都是以“##”為首碼,創建後對任何用戶都是可見的,當所有引用該表的用戶斷開連接時被刪除。

 1 --創建臨時表
 2 --方式一
 3 CREATE TABLE #表名()
 4 CREATE TABLE ##表名()
 5 --方式二
 6 SELECT INTO #表名 FROM TABLE
 7 SELECT INTO ##表名 FROM TABLE
 8 --查詢和刪除
 9 SELECT * FROM #表名
10 DROP * FROM #表名

    臨時表還可以和普通表一樣添加索引,主鍵、外鍵和約束。

    表變數本質上還是變數,所以依然使用 DECLARE 關鍵字聲明,既然是變數,那麼也分為本地及全局的兩種,本地表變數的名稱都是以“@”為首碼,只有在本地當前的用戶連接中才可以訪問。全局表變數的名稱都是以“@@”為首碼,和其他的系統全局變數一樣。

1 DECLARE @News TABLE()

    對於表變數,可以正常執行 DML。表變數一般存儲在記憶體中,並且不能添加索引和約束。

    很多時候表變數和臨時表的功能是重合的,如何選取完全取決於應用對記憶體的壓力,如果數據量比較大,可以使用臨時表,否則推薦使用表變數。

    C:CTE

    共用表表達式 CTE ,你可以把它理解為一個臨時的查詢結果集,你可以在接下來的 SELECT、INSERT、UPDATE等語句中重覆

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Exception in thread "main" java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: com/google/inject/Stage at org.testng.internal.Configuratio ...
  • 1、PGD: Page Global Directory Linux系統中每個進程對應用戶空間的pgd是不一樣的,但是linux內核 的pgd是一樣的。當創建一個新的進程時,都要為新進程創建一個新的頁面目錄PGD,並從內核的頁面目錄swapper_pg_dir中複製內核區間頁面目錄項至新建進程頁面目 ...
  • When you reinstall win10 system, the VMware dosen't work. The error is shown below: Solution: Disable Device Guard and Hyper-V (1) Disable the group p ...
  • 使用該教程,能直觀地看到java啟動腳本是否啟動/關閉成功 能讓自己的啟動時間日期都記錄在Log中 能記錄有哪些人登陸了該伺服器操作了啟動關閉腳本(記錄IP地址) ...
  • 安裝 Jenkins 後,初始化下載插件總是失敗,導致安裝不成功,重試好幾次都是卡在安裝插件那。 這裡記錄下 Docker 下怎麼安裝 Jenkins ,並解決初始安裝插件失敗問題。 安裝插件失敗,其實是拉取了官方的 Jenkins 鏡像,然後在初始化安裝插件時,會從國外的網站去獲取,導致安裝非常緩 ...
  • 相信鐵子們有很多都是將找工作的小白(和小編一樣!!嘿嘿)小編也和在座的大家一樣,一個普通的不能再普通的二本學生(北華大學) 《 單身!單身!單身!》 聽很多人都說:像我們這個樣子,害!放棄吧!回家養豬都比你那一個月3k、4k的工資高(看今年的行情好像確實)。。。 這句話對於本就不是特別強的小編來說更 ...
  • 今天比較開心,只想哈哈~哈哈哈~ 啥也不多說了,直接看示例吧!絕對比我口才好~ 哈哈!Get到了嗎?好意思不幫我分享嘛~哈哈~ 轉載請註明出處!歡迎關註本人微信公眾號【HBase工作筆記】 ...
  • C:\Program Files\mysql-5.7.10-winx64\bin># 啟動mysql服務net start mysql# 停止mysql服務net stop mysql 提示信息:'net’ 不是內部命令或外部命令,也不是可運行的程式或批處理文件 解決辦法: 我的電腦-->屬性--> ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...