日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL SERVER 2005 T_SQL新的特性以及解决并发

發布時間:2025/3/8 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL SERVER 2005 T_SQL新的特性以及解决并发 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一.修改語句的增強
UPDATE?test?SET?tname.WRITE('one?hundred?and?two',?9,?3)?WHERE?tid?=?102

在2005中增強了update方法,這是修改test表的列tname?WRITE方法是把tname這個列中從字符串9開始?把3個長的字符串改為one?hundred?and?two

二、異常的捕獲
可以捕獲過去會導致批處理終止和事務的錯誤,但是不能處理連接中斷錯誤和硬件錯誤等
--Using?the?try..catch..?construct?and?invoking?a?run-time?error
SET?XACT_ABORT?of???這個打開捕獲異常的開關?,默認是關閉的
BEGIN?TRY
???BEGIN?TRAN
????????INSERT?INTO?score?VALUES?(102,78)?
????INSERT?INTO?score?VALUES?(107,?76)?/**//*?Foreign?Key?Error?*/?
????INSERT?INTO?score?VALUES?(103,81)?
???COMMIT?TRAN
????PRINT?'Transaction?committed'
END?TRY
BEGIN?CATCH
????ROLLBACK
????PRINT?'Transaction?rolled?back'
????????SELECT?ERROR_NUMBER()?AS?ErrorNumber,
????????ERROR_SEVERITY()?AS?ErrorSeverity,
????????ERROR_STATE()?as?ErrorState,
????????ERROR_MESSAGE()?as?ErrorMessage;
END?CATCH
GO
三、快照隔離
寫入程序不會影響讀取程序,可對事務沖突的檢測
create?database?demo2??建立數據庫
go
use?demo2
alter?database?demo2?set?allow_snapshot_isolation?on??打開快照隔離開關,默認是關閉的
create?table?test
(?tid?int?not?null?primary?key,
??tname?varchar(50)?not?null
)
insert?into?test?values(1,'version1')
insert?into?test?values(2,'version2')

--connection?1

use?demo2
begin?tran
?update?test?set?tname='version3'?where?tid=2
?select?*?from?test

--connection?2
use?demo2
set?transaction?isolation?level?snapshot
select?*?from?test

--it?will?ok,?you?can?see?it?
四?、top語句的增強
可以是數字表達式,一返回要通過通過查詢影響的行輸或者百分比還可以是更具情況使用變量和子查詢
可以在delete、update和insert中使用top選項,更好的代替set?rowcount選項,使之更為有效。
--create?a?table?and?insert?some?data
use?demo
go
CREATE?TABLE?toptest?(column1?VARCHAR(150))
go
INSERT?INTO?toptest?VALUES('t1')
INSERT?INTO?toptest?VALUES('t2')
INSERT?INTO?toptest?VALUES('t3')
INSERT?INTO?toptest?VALUES('t4')
INSERT?INTO?toptest?VALUES('t5')
INSERT?INTO?toptest?VALUES('t6')
INSERT?INTO?toptest?VALUES('t7')
INSERT?INTO?toptest?VALUES('t8')
select?*?from?toptest
go

CREATE?TABLE?toptest2?(column2?VARCHAR(150))
go
INSERT?INTO?toptest2?VALUES('c1')
INSERT?INTO?toptest2?VALUES('c2')

--declare?3?variables
DECLARE?@a?INT
DECLARE?@b?INT
DECLARE?@c?INT
--set?values
SET?@a?=?10
SET?@b?=?5
SELECT?@c?=?@a/@b
--use?the?calculated?expression
SELECT?TOP(@c)?*?FROM?toptest
--use?a?SELECT?statement?as?expression
SELECT?TOP(SELECT?COUNT(*)?FROM?toptest2)?*?
FROM?toptest

--DML?top
DELETE?TOP(2)?toptest?where?column1>'t6'
--this?sets?'t1'?and?'t2'?to?'hi'
UPDATE?TOP(2)?toptest?SET?column1?=?'hi'?where?column1<='t2'

SELECT?*?FROM?toptest
五、output
引入一個新的output字句?可以使您從修改語句(elete、update和insert)中將數據返回到表變量中
語法:output?<dml_select_list>?into?@table_variable
可以通過應用插入的表和刪除的表來訪問被修改的行的舊/新映象,起方式于訪問觸發器類似,在insert語句中,只能訪問插入的表,update和delete也一樣。訪問臨時表
--create?table?and?insert?data
use?demo
go
CREATE?TABLE?tt?
(id?INT?IDENTITY,?c1?VARCHAR(15))
go
INSERT?INTO?tt?VALUES?('r1')
INSERT?INTO?tt?VALUES?('r2')
INSERT?INTO?tt?VALUES?('r5')
INSERT?INTO?tt?VALUES?('r6')
INSERT?INTO?tt?VALUES?('r7')
INSERT?INTO?tt?VALUES?('r8')
INSERT?INTO?tt?VALUES?('r9')
INSERT?INTO?tt?VALUES?('r10')

--make?a?table?variable?to?hold?the?results?of?the?OUTPUT?clause
DECLARE?@del?AS?TABLE?(deletedId?INT,?deletedValue?VARCHAR(15))
DELETE?tt
OUTPUT?DELETED.id,?DELETED.c1?INTO?@del
WHERE?id?<?3
SELECT?*?FROM?@del
GO

六、函數
ROW_NUMBER是結果集的順序,?而不是數據庫中紀錄存放的原始順序
SELECT?orderid,qty,
??ROW_NUMBER()?OVER(ORDER?BY?qty)?AS?rownumber,
??RANK()???????OVER(ORDER?BY?qty)?AS?rank,
??DENSE_RANK()?OVER(ORDER?BY?qty)?AS?denserank?
FROM?rankorder
ORDER?BY?qty
七、通用表達式?cte?臨時命名的結果集
USE?AdventureWorks
GO
WITH?SalesCTE(ProductID,?SalesOrderID)
AS?
(
????SELECT?ProductID,?COUNT(SalesOrderID)?
????FROM?Sales.SalesOrderDetail?
????GROUP?BY?ProductID
)
SELECT?*?FROM?SalesCTE
----


--?Using?CTEs?Recursively
use?demo
go
CREATE?TABLE?CarParts
(
????CarID?int?NOT?NULL,
????Part?varchar(15),
????SubPart?varchar(15),
????Qty?int
)
GO
INSERT?CarParts?
VALUES?(1,?'Body',?'Door',?4)
INSERT?CarParts?
VALUES?(1,?'Body',?'Trunk?Lid',?1)
INSERT?CarParts?
VALUES?(1,?'Body',?'Car?Hood',?1)
INSERT?CarParts?
VALUES?(1,?'Door',?'Handle',?1)
INSERT?CarParts?
VALUES?(1,?'Door',?'Lock',?1)
INSERT?CarParts?
VALUES?(1,?'Door',?'Window',?1)
INSERT?CarParts?
VALUES?(1,?'Body',?'Rivets',?1000)
INSERT?CarParts?
VALUES?(1,?'Door',?'Rivets',?100)
INSERT?CarParts?
VALUES?(1,?'Door',?'Mirror',?1)
go
select?*?from?CarParts
go

WITH?CarPartsCTE(SubPart,?Qty)?
AS
(
????--?Anchor?Member?(AM):
????--?SELECT?query?that?doesn’t?refer?back?to?CarPartsCTE
????SELECT?SubPart,?Qty
????FROM?CarParts
????WHERE?Part?=?'Body'
????UNION?ALL
????--?Recursive?Member?(RM):
????--?SELECT?query?that?refers?back?to?CarPartsCTE
????SELECT?CarParts.SubPart,?CarPartsCTE.Qty?*?CarParts.Qty
????FROM?CarPartsCTE?
????INNER?JOIN?CarParts?ON?CarPartsCTE.SubPart?=?CarParts.Part
????WHERE?CarParts.CarID?=?1
)
--outer?query
SELECT?SubPart,?SUM(Qty)?AS?TotalNUM
FROM?CarPartsCTE
GROUP?BY?SubPart
八、新的關系運算符
pivot???把行轉回為列
unpivot?把列轉回為行
use?demo
go

create?table?orders
(Customer?varchar(10)?not?null,
?product?varchar(20)?not?null,
?quantity?int?not?null)
go
insert?orders?values('Mike',?'Bike',3)
insert?orders?values('Mike','Chain',2)
insert?orders?values('Mike','Bike',5)
insert?orders?values('Lisa','Bike',3)
insert?orders?values('Lisa','Chain',3)
insert?orders?values('Lisa','Chain',4)
insert?orders?values('Lisa','Bike',2)

select?*?from?orders

select?*?from?orders
pivot?(sum(quantity)?for?product?in?([Bike],[Chain]))?as?a
use?demo
go
CREATE?TABLE?SALES1
(
[Year]?INT,
Quarter?CHAR(2),
Amount?FLOAT
)
GO
INSERT?INTO?SALES1?VALUES?(2001,?'Q1',?80)
INSERT?INTO?SALES1?VALUES?(2001,?'Q2',?70)
INSERT?INTO?SALES1?VALUES?(2001,?'Q3',?55)
INSERT?INTO?SALES1?VALUES?(2001,?'Q3',?110)
INSERT?INTO?SALES1?VALUES?(2001,?'Q4',?90)
INSERT?INTO?SALES1?VALUES?(2002,?'Q1',?200)
INSERT?INTO?SALES1?VALUES?(2002,?'Q2',?150)
INSERT?INTO?SALES1?VALUES?(2002,?'Q2',?40)
INSERT?INTO?SALES1?VALUES?(2002,?'Q2',?60)
INSERT?INTO?SALES1?VALUES?(2002,?'Q3',?120)
INSERT?INTO?SALES1?VALUES?(2002,?'Q3',?110)
INSERT?INTO?SALES1?VALUES?(2002,?'Q4',?180)
GO

SELECT?*?FROM?SALES1
PIVOT
(SUM?(Amount)?--Aggregate?the?Amount?column?using?SUM
FOR?[Quarter]?--Pivot?the?Quarter?column?into?column?headings
IN?(Q1,?Q2,?Q3,?Q4))?--use?these?quarters
AS?P
GO

select?*?into?temp1?from?orders
pivot?(sum(quantity)?for?product?in?([Bike],[Chain]))?as?a

select?*?from?temp1

select?customer,?product,quantity
froam?temp1
unpivot(quantity?for?product?in?([Bike],[Chain]))?as?a
九、ddl觸發器
use?demo
go
CREATE?TRIGGER?prevent_drop_table?ON?DATABASE?FOR?DROP_TABLE
AS
RAISERROR('Not?allowed?to?drop?tables.',?10,?1)
PRINT?'DROP?TABLE?attempt?in?database?'?+?DB_NAME()?+?'.'
PRINT?CONVERT?(nvarchar?(1000),EventData())
ROLLBACK
GO
--?test
CREATE?TABLE?TestDROP(col1?INT)
go
INSERT?INTO?TestDROP?VALUES(1)

drop?talbe?testdrop

--?Server
CREATE?TRIGGER?audit_ddl_logins?ON?ALL?SERVER
??FOR?CREATE_LOGIN,?ALTER_LOGIN,?DROP_LOGIN
AS
PRINT?'DDL?LOGIN?took?place.'
PRINT?CONVERT?(nvarchar?(1000),EventData())
GO

--?test
CREATE?LOGIN?login1?WITH?PASSWORD?=?'123'
ALTER?LOGIN?login1?WITH?PASSWORD?=?'xyz'
DROP?LOGIN?login1 豐富的數據類型?Richer?Data?Types?

1、varchar(max)、nvarchar(max)和varbinary(max)數據類型最多可以保存2GB的數據,可以取代text、ntext或image數據類型。
CREATE?TABLE?myTable
(
????id?INT,
????content?VARCHAR(MAX)
)

2、XML數據類型
XML數據類型允許用戶在SQL?Server數據庫中保存XML片段或文檔。

錯誤處理?Error?Handling?

1、新的異常處理結構

2、可以捕獲和處理過去會導致批處理終止的錯誤
前提是這些錯誤不會導致連接中斷(通常是嚴重程度為21以上的錯誤,例如,表或數據庫完整性可疑、硬件錯誤等等。)。

3、TRY/CATCH?構造
SET?XACT_ABORT?ON
???BEGIN?TRY
?????<core?logic>
???END?TRY
???BEGIN?CATCH?TRAN_ABORT
?????<exception?handling?logic>
???END?TRY

@@error?may?be?quired?as?first?statement?in?CATCH?block

4、演示代碼
USE?demo
??GO
??--創建工作表

??CREATE?TABLE?student
??(?
??????stuid?INT?NOT?NULL?PRIMARY?KEY,
??????stuname?VARCHAR(50)
??)

??CREATE?TABLE?score?
??(
??????stuid?INT?NOT?NULL?REFERENCES?student(stuid),
??????score?INT
??)
GO

INSERT?INTO?student?VALUES?(101,'zhangsan')?
INSERT?INTO?student?VALUES?(102,'wangwu')?
INSERT?INTO?student?VALUES?(103,'lishi')?
INSERT?INTO?student?VALUES?(104,'maliu')?

--調用一個運行時錯誤
SET?XACT_ABORT?OFF
??BEGIN?TRAN
?????INSERT?INTO?score?VALUES?(101,90)
?????INSERT?INTO?score?VALUES?(102,78)?
?????INSERT?INTO?score?VALUES?(107,?76)?/**//*?外鍵錯誤?*/?
?????INSERT?INTO?score?VALUES?(103,81)?
?????INSERT?INTO?score?VALUES?(104,65)?
??COMMIT?TRAN
??GO

??SELECT?*?FROM?student
??SELECT?*?FROM?score

--使用TRYCATCH構造,并調用一個運行時錯誤
SET?XACT_ABORT?OFF
??BEGIN?TRY
????BEGIN?TRAN
???????INSERT?INTO?score?VALUES?(101,90)
???????INSERT?INTO?score?VALUES?(102,78)?
???????INSERT?INTO?score?VALUES?(107,?76)?/**//*?外鍵錯誤?*/?
???????INSERT?INTO?score?VALUES?(103,81)?
???????INSERT?INTO?score?VALUES?(104,65)?
????COMMIT?TRAN
????PRINT?'事務提交'
??END?TRY
??BEGIN?CATCH
????ROLLBACK
?????PRINT?'事務回滾'
????????SELECT?ERROR_NUMBER()?AS?ErrorNumber,
????????ERROR_SEVERITY()?AS?ErrorSeverity,
????????ERROR_STATE()?as?ErrorState,
????????ERROR_MESSAGE()?as?ErrorMessage;
???END?CATCH
GO

SELECT?*?FROM?score
GO

快照隔離?Snapshot?Isolation

1、寫入程序不會阻礙讀取程序
2、Snapshot?isolation?must?be?enabled?for?DB
??????ALTER?DATABASE?數據庫?SET?allow_snapshot_isolation?ON
3、Snapshot?isolation?must?be?enabled?for?connection
??????Set?transaction?isolation?level?snapshot
4、UPDATE?transactions?keep?old?versions?of?data?in?a?linked?list
5、新的隔離級別提供了以下優點:
 ?1)?提高了只讀應用程序的數據可用性
 ?2)?允許在OLTP環境中執行非阻止讀取操作
 ?3)?可對寫入事務進行自動的強制沖突檢測
6、演示代碼
CREATE?DATABASE?demo2
GO
USE?demo2
???ALTER?DATABASE?demo2?SET?allow_snapshot_isolation?ON
???CREATE?TABLE?test
???(?
?????tid?INT?NOT?NULL?primary?key,
?????tname?VARCHAR(50)?NOT?NULL
???)
??INSERT?INTO?test?VALUES(1,'version1')
??INSERT?INTO?test?VALUES(2,'version2')

--連接一

USE?demo2
BEGIN?TRAN
???UPDATE?test?SET?tname='version3'?WHERE?tid=2
???SELECT?*?FROM?test

--連接二
USE?demo2
???SET?transaction?isolation?level?snapshot
???SELECT?*?FROM?test?

TOP?增強功能

1、TOP?增強
可以指定一個數字表達式,以返回要通過查詢影響的行數或百分比,還可以根據情況使用變量或子查詢。
可以在DELETE、UPDATE和INSERT查詢中使用TOP選項。

2、更好地替換SET?ROWCOUNT選項,使之更為有效。

OUTPUT

1、SQL?Server?2005引入一個新的OUTPUT子句,以使您可以沖修改語句(INSERT、UPDATE、DELETE)中將數據返回到表變量中。

2、新的OUTPUT子局的語法為:
OUTPUT?<dml_select_list>?INTO?@table_variable
可以通過引用插入的表或刪除的表來訪問被修改的行的舊/新影象,其方式與訪問觸發器類似。在INSERT語句中,只能訪問插入的表。在DELETE語句中,只能訪問刪除的表。在UPDATE語句中,可以訪問插入的表和刪除的表。

3、代碼演示
USE?demo
GO
CREATE?TABLE?tt?
(
??id?INT?IDENTITY,?
??c1?VARCHAR(15)
)
GO

INSERT?INTO?tt?VALUES?('r1')
INSERT?INTO?tt?VALUES?('r2')
INSERT?INTO?tt?VALUES?('r5')
INSERT?INTO?tt?VALUES?('r6')
INSERT?INTO?tt?VALUES?('r7')
INSERT?INTO?tt?VALUES?('r8')
INSERT?INTO?tt?VALUES?('r9')
INSERT?INTO?tt?VALUES?('r10')

DECLARE?@del?AS?TABLE?(deletedId?INT,?deletedValue?VARCHAR(15))
DELETE?tt
OUTPUT?DELETED.id,?DELETED.c1?INTO?@del
WHERE?id?<?3
SELECT?*?FROM?@del
GO
-----------------------------------------------
USE?demo
GO
CREATE?TABLE?toptest?(column1?VARCHAR(150))
GO
INSERT?INTO?toptest?VALUES('t1')
INSERT?INTO?toptest?VALUES('t2')
INSERT?INTO?toptest?VALUES('t3')
INSERT?INTO?toptest?VALUES('t4')
INSERT?INTO?toptest?VALUES('t5')
INSERT?INTO?toptest?VALUES('t6')
INSERT?INTO?toptest?VALUES('t7')
INSERT?INTO?toptest?VALUES('t8')
SELECT?*?FROM?toptest
GO

CREATE?TABLE?toptest2?(column2?VARCHAR(150))
GO
INSERT?INTO?toptest2?VALUES('c1')
INSERT?INTO?toptest2?VALUES('c2')

--聲明3個變量
DECLARE?@a?INT
DECLARE?@b?INT
DECLARE?@c?INT

--賦值
SET?@a?=?10
SET?@b?=?5
SELECT?@c?=?@a/@b

--使用計算表達式
SELECT?TOP(@c)?*?FROM?toptest

--使用SELECT語句作為條件
SELECT?TOP(SELECT?COUNT(*)?FROM?toptest2)?*?
FROM?toptest

--指出top
DELETE?TOP(2)?toptest?where?column1>'t6'

--更新top
UPDATE?TOP(2)?toptest?SET?column1?=?'hi'?where?column1<='t2'

SELECT?*?FROM?toptest

排序函數?Ranking?Functions

1、SQL?Server引入幾個新的排序函數:如ROW_NUMBER、RANK、DENSE_RANK等。這些新函數使您可以有效地分析數據以及向查詢的結果行提供排序值。

2、排序函數都遵循類似的語法模式:
()OVER
([PARTITION?BY]
ORDER?BY)
該函數只能在查詢的兩個子句中指定?-?在SELECT子句或ORDER?BY子句中。以下詳細討論不同的函數。??

3、ROW_NUMBER
ROW_NUMBER是結果集的順序,?而不是數據庫中紀錄存放的原始順序
USE?demo
GO
CREATE?TABLE?rankorder
(
?orderid?INT,
?qty?INT
)
GO
INSERT?rankorder?VALUES(30001,10)
INSERT?rankorder?VALUES(10001,10)
INSERT?rankorder?VALUES(10006,10)
INSERT?rankorder?VALUES(40005,10)
INSERT?rankorder?VALUES(30003,15)
INSERT?rankorder?VALUES(30004,20)
INSERT?rankorder?VALUES(20002,20)
INSERT?rankorder?VALUES(20001,20)
INSERT?rankorder?VALUES(10005,30)
INSERT?rankorder?VALUES(30007,30)
INSERT?rankorder?VALUES(40001,40)
GO
SELECT?orderid,qty,
??ROW_NUMBER()?OVER(ORDER?BY?qty)?AS?rownumber,
??RANK()???????OVER(ORDER?BY?qty)?AS?rank,
??DENSE_RANK()?OVER(ORDER?BY?qty)?AS?denserank?
FROM?rankorder
ORDER?BY?qty

通用表表達式?Common?Table?Expressions??

通 用表表達式(CTE)是一個可以由定義語句引用的臨時表命名的結果集。在他們的簡單形式中,您可以將CTE視為類似于視圖和派生表混合功能的改進版本。在 查詢的FROM子句中引用CTE的方式類似于引用派生表和視圖的方式。只須定義CTE一次,即可在查詢中多次引用它。在CTE的定義中,可以引用在同一批 處理中定義的變量。但是CTE的真正威力在于它們的遞歸功能,即CTE可以包含對它們自身的引用。

視圖、派生表和CTE內部的查詢的一般形式

1、視圖
CREATE?VIEW?<view_name>(<column_aliases>)?AS?<view_query>

2、派生表
SELECT?*?FROM?(<derived_table)query>)?AS?<dericed_table_alias>(<column_aliases>)

3、CTE
WITH?<cte_alias>(<column_aliases>)
AS
{
?<cte_query>
)
SELECT?*?FROM?<cte_alias]>
在關鍵字WITH之后,為CTE提供一個別名,并且為它的結果列提供一個可選的別名列表;編寫CTE的主體;然后從外部查詢中引用它。

4、演示代碼
USE?AdventureWorks
GO
WITH?SalesCTE(ProductID,?SalesOrderID)
AS?
(
?SELECT?ProductID,?COUNT(SalesOrderID)?
?FROM?Sales.SalesOrderDetail?
?GROUP?BY?ProductID
)
SELECT?*?FROM?SalesCTE

Recursive?CTEs?遞歸的通用表表達式

遞歸的CTE是根據至少兩個查詢(或者稱為兩個成員)構建的,一個是非遞歸查詢,也成為固定成員,只能調用一次,另外一個是遞歸查詢,也成為遞歸成員(RM),可以反復調用,直到查詢不再返回行。查詢由UNION?ALL運算符連接為一個單獨的CTE。

--使用遞歸的通用表表達式
USE?demo
GO
CREATE?TABLE?CarParts
(
?CarID?INT?NOT?NULL,
?Part?VARCHAR(15),
?SubPart?VARCHAR(15),
?Qty?INT
)
GO
INSERT?CarParts?VALUES?(1,?'Body',?'Door',?4)
INSERT?CarParts?VALUES?(1,?'Body',?'Trunk?Lid',?1)
INSERT?CarParts?VALUES?(1,?'Body',?'Car?Hood',?1)
INSERT?CarParts?VALUES?(1,?'Door',?'Handle',?1)
INSERT?CarParts?VALUES?(1,?'Door',?'Lock',?1)
INSERT?CarParts?VALUES?(1,?'Door',?'Window',?1)
INSERT?CarParts?VALUES?(1,?'Body',?'Rivets',?1000)
INSERT?CarParts?VALUES?(1,?'Door',?'Rivets',?100)
INSERT?CarParts?VALUES?(1,?'Door',?'Mirror',?1)
GO
SELECT?*?FROM?CarParts
GO

WITH?CarPartsCTE(SubPart,?Qty)?
AS
(
?--?固定成員?(AM):
?--?SELECT查詢無需參考CarPartsCTE
?SELECT?SubPart,?Qty
?FROM?CarParts
?WHERE?Part?=?'Body'
?UNION?ALL
?--?遞歸成員?(RM):
?--?SELECT查詢參考CarPartsCTE
?SELECT?CarParts.SubPart,?CarPartsCTE.Qty?*?CarParts.Qty
?FROM?CarPartsCTE?
?INNER?JOIN?CarParts?ON?CarPartsCTE.SubPart?=?CarParts.Part
?WHERE?CarParts.CarID?=?1
)
--?外部查詢
SELECT?SubPart,?SUM(Qty)?AS?TotalNUM
FROM?CarPartsCTE
GROUP?BY?SubPart???

新的關系運算符?PIVOT/UNPIVOT/APPLY

1、PIVOT
PIVOT運算符將行旋轉為列,并且可能同時執行聚合。使用PIVOT運算符時要注意的重要一點是,需要為它提供一個查詢表達式,表達式使用視圖、派生表或者是CTE只返回所關注的列。

2、UNPIVOT
UNPIVOT運算符執行與PIVOT運算符相反的操作;他將列旋轉為行了。

3、APPLY
APPLY關系運算符允許您對外部表的每個行調用指定的表值函數一次。您可以在查詢的FROM子句中指定APPLY,其方式與使用JOIN關系運算符類似。APPLY具有兩種形式:CROSS?APPLY和OUTER?APPLY。

演示:

USE?demo
GO

CREATE?TABLE?orders
(
?Customer?VARCHAR(10)?NOT?NULL,
?product?VARCHAR(20)?NOT?NULL,
?quantity?INT?NOT?NULL
)
GO
INSERT?orders?VALUES('Mike',?'Bike',3)
INSERT?orders?VALUES('Mike','Chain',2)
INSERT?orders?VALUES('Mike','Bike',5)
INSERT?orders?VALUES('Lisa','Bike',3)
INSERT?orders?VALUES('Lisa','Chain',3)
INSERT?orders?VALUES('Lisa','Chain',4)
INSERT?orders?VALUES('Lisa','Bike',2)

SELECT?*?FROM?orders

SELECT?*?FROM?orders
PIVOT?(SUM(quantity)?FOR?product?IN?([Bike],[Chain]))?AS?a
USE?demo
GO
CREATE?TABLE?SALES1
(
??[Year]?INT,
??Quarter?CHAR(2),
??Amount?FLOAT
)
GO
INSERT?INTO?SALES1?VALUES?(2001,?'Q1',?80)
INSERT?INTO?SALES1?VALUES?(2001,?'Q2',?70)
INSERT?INTO?SALES1?VALUES?(2001,?'Q3',?55)
INSERT?INTO?SALES1?VALUES?(2001,?'Q3',?110)
INSERT?INTO?SALES1?VALUES?(2001,?'Q4',?90)
INSERT?INTO?SALES1?VALUES?(2002,?'Q1',?200)
INSERT?INTO?SALES1?VALUES?(2002,?'Q2',?150)
INSERT?INTO?SALES1?VALUES?(2002,?'Q2',?40)
INSERT?INTO?SALES1?VALUES?(2002,?'Q2',?60)
INSERT?INTO?SALES1?VALUES?(2002,?'Q3',?120)
INSERT?INTO?SALES1?VALUES?(2002,?'Q3',?110)
INSERT?INTO?SALES1?VALUES?(2002,?'Q4',?180)
GO

SELECT?*?FROM?SALES1
PIVOT
(SUM?(Amount)?--使用SUM聚合數量列
FOR?[Quarter]?--PIVOT?Quarter?列
IN?(Q1,?Q2,?Q3,?Q4))?--使用季節
AS?P
GO

SELECT?*?INTO?temp1?FROM?orders
PIVOT?(sum(quantity)?FOR?product?IN?([Bike],[Chain]))?AS?a

SELECT?*?FROM?temp1

SELECT?customer,?product,quantity
FROM?temp1
UNPIVOT(quantity?FOR?product?IN?([Bike],[Chain]))?AS?a
----------------------------------------------------
USE?demo
GO
CREATE?TABLE?Arrays
(
??aid?INT?NOT?NULL?IDENTITY?PRIMARY?KEY,
??array?VARCHAR(7999)?NOT?NULL
)
GO
INSERT?INTO?Arrays?VALUES('')
INSERT?INTO?Arrays?VALUES('10')
INSERT?INTO?Arrays?VALUES('20,40,30')
INSERT?INTO?Arrays?VALUES('-1,-3,-5')
GO
CREATE?FUNCTION??function1(@arr?AS?VARCHAR(7999))
??RETURNS?@t?TABLE(pos?INT?NOT?NULL,?value?INT?NOT?NULL)
AS
BEGIN
??DECLARE?@end?AS?INT,?@start?AS?INT,?@pos?AS?INT
??SELECT?@arr?=?@arr?+?',',?@pos?=?1,
????@start?=?1,?@end?=?CHARINDEX(',',?@arr,?@start)
??WHILE?@end?>?1
??BEGIN
????INSERT?INTO?@t?VALUES(@pos,?SUBSTRING(@arr,?@start,?@end?-?@start))

????SELECT?@pos?=?@pos?+?1,
??????@start?=?@end?+?1,?@end?=?CHARINDEX(',',?@arr,?@start)
??END
??RETURN
END

--測試
SELECT?*?FROM?function1('200,400,300')
GO

SELECT?A.aid,?F.*
FROM?Arrays?AS?A
??CROSS?APPLY?function1(array)?AS?F
GO
SELECT?A.aid,?F.*
FROM?Arrays?AS?A
??OUTER?APPLY?function1(array)?AS?F
GO

DDL觸發器?DDL?Triggers

SQL?Server?2005 可以就整個服務器或數據庫的某個范圍為DDL事件定義觸發器。也可以為單個DDL語句(例如:CREAT_TABLE、DROP_TABLE等)或者為一 組語句(例如:指定DDL_DATABASE_LEVEL_EVENTS想要觸發器觸發數據庫所有DDL事件)定義DDL觸發器。

在DDL觸發器內部,可以通過訪問eventdata()函數獲得與激發該觸發器的事件有關的數據。該eventdata()函數返回有關事件的xml數據。

DDL觸發器特別有用的方案包括DDL更改的完整性檢查、審核方案以及其他方案。

代碼演示:

USE?demo
GO
CREATE?TRIGGER?prevent_drop_table?ON?DATABASE?FOR?DROP_TABLE
AS
RAISERROR('沒有刪除表的權限.',?10,?1)
PRINT?'嘗試在數據庫'?+?DB_NAME()?+?'中刪除表.'
PRINT?CONVERT?(nvarchar?(1000),EventData())
ROLLBACK
GO
--?測試
CREATE?TABLE?TestDROP(col1?INT)
GO
INSERT?INTO?TestDROP?VALUES(1)

DROP?TABLE?testdrop

--?Server
CREATE?TRIGGER?audit_ddl_logins?ON?ALL?SERVER
??FOR?CREATE_LOGIN,?ALTER_LOGIN,?DROP_LOGIN
AS
PRINT?'發生DDL?LOGIN.'
PRINT?CONVERT?(nvarchar?(1000),EventData())
GO

--?測試
CREATE?LOGIN?login1?WITH?PASSWORD?=?'123'
ALTER?LOGIN?login1?WITH?PASSWORD?=?'xyz'
DROP?LOGIN?login1
SQL?Server?2005?在Transaction-SQL上所做的改進反映了其更好地滿足了ANSI-99?SQL規范的要求以及客戶的需求。

create?????proc?[dbo].[Name_Add]
?@Name?varchar(50)
as
begin

begin?tran
insert?Names?(Name)
select?(@Name)?where?not?exists?(select?NameId?from?Names?with(HOLDLOCK)?where?Name?=?@Name)
commit?tran

select?NameId,Name?from?Names?with(nolock)?where?Name?=?@Name
end

?要點:檢查,加鎖,插入值在一句sql中完成.這樣再大的并發也不怕了.

總結

以上是生活随笔為你收集整理的SQL SERVER 2005 T_SQL新的特性以及解决并发的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。