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

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:
None.gif一.修改语句的增强
None.gif UPDATE test SET tname.WRITE( ' one hundred and two ', 9, 3) WHERE tid = 102
None.gif
None.gif在2005中增强了update方法,这是修改test表的列tname WRITE方法是把tname这个列中从字符串9开始 把3个长的字符串改为one hundred and two
None.gif
None.gif二、异常的捕获
None.gif可以捕获过去会导致批处理终止和事务的错误,但是不能处理连接中断错误和硬件错误等
None.gif -- Using the try..catch.. construct and invoking a run-time error
None.gif
SET XACT_ABORT of 这个打开捕获异常的开关 ,默认是关闭的
None.gif BEGIN TRY
None.gif BEGIN TRAN
None.gif INSERT INTO score VALUES ( 102, 78)
ExpandedBlockStart.gif ContractedBlock.gif INSERT INTO score VALUES ( 107, 76) /**/ /* Foreign Key Error */
None.gif INSERT INTO score VALUES ( 103, 81)
None.gif COMMIT TRAN
None.gif PRINT ' Transaction committed '
None.gif END TRY
None.gif BEGIN CATCH
None.gif ROLLBACK
None.gif PRINT ' Transaction rolled back '
None.gif SELECT ERROR_NUMBER() AS ErrorNumber,
None.gif ERROR_SEVERITY() AS ErrorSeverity,
None.gif ERROR_STATE() as ErrorState,
None.gif ERROR_MESSAGE() as ErrorMessage;
None.gif END CATCH
None.gif GO
None.gif三、快照隔离
None.gif写入程序不会影响读取程序,可对事务冲突的检测
None.gif create database demo2 建立数据库
None.gif go
None.gif use demo2
None.gif alter database demo2 set allow_snapshot_isolation on 打开快照隔离开关,默认是关闭的
None.gif create table test
None.gif( tid int not null primary key,
None.gif tname varchar( 50) not null
None.gif)
None.gif insert into test values( 1, ' version1 ')
None.gif insert into test values( 2, ' version2 ')
None.gif
None.gif -- connection 1
None.gif

None.gif use demo2
None.gif begin tran
None.gif update test set tname = ' version3 ' where tid = 2
None.gif select * from test
None.gif
None.gif -- connection 2
None.gif
use demo2
None.gif set transaction isolation level snapshot
None.gif select * from test
None.gif
None.gif -- it will ok, you can see it
None.gif
四 、top语句的增强
None.gif可以是数字表达式,一返回要通过通过查询影响的行输或者百分比还可以是更具情况使用变量和子查询
None.gif可以在delete、update和insert中使用top选项,更好的代替set rowcount选项,使之更为有效。
None.gif -- create a table and insert some data
None.gif
use demo
None.gif go
None.gif CREATE TABLE toptest (column1 VARCHAR( 150))
None.gif go
None.gif INSERT INTO toptest VALUES( ' t1 ')
None.gif INSERT INTO toptest VALUES( ' t2 ')
None.gif INSERT INTO toptest VALUES( ' t3 ')
None.gif INSERT INTO toptest VALUES( ' t4 ')
None.gif INSERT INTO toptest VALUES( ' t5 ')
None.gif INSERT INTO toptest VALUES( ' t6 ')
None.gif INSERT INTO toptest VALUES( ' t7 ')
None.gif INSERT INTO toptest VALUES( ' t8 ')
None.gif select * from toptest
None.gif go
None.gif
None.gif CREATE TABLE toptest2 (column2 VARCHAR( 150))
None.gif go
None.gif INSERT INTO toptest2 VALUES( ' c1 ')
None.gif INSERT INTO toptest2 VALUES( ' c2 ')
None.gif
None.gif -- declare 3 variables
None.gif
DECLARE @a INT
None.gif DECLARE @b INT
None.gif DECLARE @c INT
None.gif -- set values
None.gif
SET @a = 10
None.gif SET @b = 5
None.gif SELECT @c = @a / @b
None.gif -- use the calculated expression
None.gif
SELECT TOP( @c) * FROM toptest
None.gif -- use a SELECT statement as expression
None.gif
SELECT TOP( SELECT COUNT( *) FROM toptest2) *
None.gif FROM toptest
None.gif
None.gif -- DML top
None.gif
DELETE TOP( 2) toptest where column1 > ' t6 '
None.gif -- this sets 't1' and 't2' to 'hi'
None.gif
UPDATE TOP( 2) toptest SET column1 = ' hi ' where column1 <= ' t2 '
None.gif
None.gif SELECT * FROM toptest
None.gif五、output
None.gif引入一个新的output字句 可以使您从修改语句(elete、update和insert)中将数据返回到表变量中
None.gif语法:output <dml_select_list > into @table_variable
None.gif可以通过应用插入的表和删除的表来访问被修改的行的旧 /新映象,起方式于访问触发器类似,在insert语句中,只能访问插入的表,update和delete也一样。访问临时表
None.gif -- create table and insert data
None.gif
use demo
None.gif go
None.gif CREATE TABLE tt
None.gif(id INT IDENTITY, c1 VARCHAR( 15))
None.gif go
None.gif INSERT INTO tt VALUES ( ' r1 ')
None.gif INSERT INTO tt VALUES ( ' r2 ')
None.gif INSERT INTO tt VALUES ( ' r5 ')
None.gif INSERT INTO tt VALUES ( ' r6 ')
None.gif INSERT INTO tt VALUES ( ' r7 ')
None.gif INSERT INTO tt VALUES ( ' r8 ')
None.gif INSERT INTO tt VALUES ( ' r9 ')
None.gif INSERT INTO tt VALUES ( ' r10 ')
None.gif
None.gif -- make a table variable to hold the results of the OUTPUT clause
None.gif
DECLARE @del AS TABLE (deletedId INT, deletedValue VARCHAR( 15))
None.gif DELETE tt
None.gifOUTPUT DELETED.id, DELETED.c1 INTO @del
None.gif WHERE id < 3
None.gif SELECT * FROM @del
None.gif GO
None.gif
None.gif六、函数
None.gifROW_NUMBER是结果集的顺序, 而不是数据库中纪录存放的原始顺序
None.gif SELECT orderid,qty,
None.gif ROW_NUMBER() OVER( ORDER BY qty) AS rownumber,
None.gif RANK() OVER( ORDER BY qty) AS rank,
None.gif DENSE_RANK() OVER( ORDER BY qty) AS denserank
None.gif FROM rankorder
None.gif ORDER BY qty
None.gif七、通用表达式 cte 临时命名的结果集
None.gif USE AdventureWorks
None.gif GO
None.gif WITH SalesCTE(ProductID, SalesOrderID)
None.gif AS
None.gif(
None.gif SELECT ProductID, COUNT(SalesOrderID)
None.gif FROM Sales.SalesOrderDetail
None.gif GROUP BY ProductID
None.gif)
None.gif SELECT * FROM SalesCTE
None.gif -- --
None.gif

None.gif
None.gif -- Using CTEs Recursively
None.gif
use demo
None.gif go
None.gif CREATE TABLE CarParts
None.gif(
None.gif CarID int NOT NULL,
None.gif Part varchar( 15),
None.gif SubPart varchar( 15),
None.gif Qty int
None.gif)
None.gif GO
None.gif INSERT CarParts
None.gif VALUES ( 1, ' Body ', ' Door ', 4)
None.gif INSERT CarParts
None.gif VALUES ( 1, ' Body ', ' Trunk Lid ', 1)
None.gif INSERT CarParts
None.gif VALUES ( 1, ' Body ', ' Car Hood ', 1)
None.gif INSERT CarParts
None.gif VALUES ( 1, ' Door ', ' Handle ', 1)
None.gif INSERT CarParts
None.gif VALUES ( 1, ' Door ', ' Lock ', 1)
None.gif INSERT CarParts
None.gif VALUES ( 1, ' Door ', ' Window ', 1)
None.gif INSERT CarParts
None.gif VALUES ( 1, ' Body ', ' Rivets ', 1000)
None.gif INSERT CarParts
None.gif VALUES ( 1, ' Door ', ' Rivets ', 100)
None.gif INSERT CarParts
None.gif VALUES ( 1, ' Door ', ' Mirror ', 1)
None.gif go
None.gif select * from CarParts
None.gif go
None.gif
None.gif WITH CarPartsCTE(SubPart, Qty)
None.gif AS
None.gif(
None.gif -- Anchor Member (AM):
None.gif
-- SELECT query that doesn’t refer back to CarPartsCTE
None.gif
SELECT SubPart, Qty
None.gif FROM CarParts
None.gif WHERE Part = ' Body '
None.gif UNION ALL
None.gif -- Recursive Member (RM):
None.gif
-- SELECT query that refers back to CarPartsCTE
None.gif
SELECT CarParts.SubPart, CarPartsCTE.Qty * CarParts.Qty
None.gif FROM CarPartsCTE
None.gif INNER JOIN CarParts ON CarPartsCTE.SubPart = CarParts.Part
None.gif WHERE CarParts.CarID = 1
None.gif)
None.gif -- outer query
None.gif
SELECT SubPart, SUM(Qty) AS TotalNUM
None.gif FROM CarPartsCTE
None.gif GROUP BY SubPart
None.gif八、新的关系运算符
None.gifpivot 把行转回为列
None.gifunpivot 把列转回为行
None.gif use demo
None.gif go
None.gif
None.gif create table orders
None.gif(Customer varchar( 10) not null,
None.gif product varchar( 20) not null,
None.gif quantity int not null)
None.gif go
None.gif insert orders values( ' Mike ', ' Bike ', 3)
None.gif insert orders values( ' Mike ', ' Chain ', 2)
None.gif insert orders values( ' Mike ', ' Bike ', 5)
None.gif insert orders values( ' Lisa ', ' Bike ', 3)
None.gif insert orders values( ' Lisa ', ' Chain ', 3)
None.gif insert orders values( ' Lisa ', ' Chain ', 4)
None.gif insert orders values( ' Lisa ', ' Bike ', 2)
None.gif
None.gif select * from orders
None.gif
None.gif select * from orders
None.gifpivot ( sum(quantity) for product in ( [ Bike ], [ Chain ])) as a
None.gif use demo
None.gif go
None.gif CREATE TABLE SALES1
None.gif(
None.gif [ Year ] INT,
None.gifQuarter CHAR( 2),
None.gifAmount FLOAT
None.gif)
None.gif GO
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q1 ', 80)
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q2 ', 70)
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q3 ', 55)
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q3 ', 110)
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q4 ', 90)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q1 ', 200)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q2 ', 150)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q2 ', 40)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q2 ', 60)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q3 ', 120)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q3 ', 110)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q4 ', 180)
None.gif GO
None.gif
None.gif SELECT * FROM SALES1
None.gifPIVOT
None.gif( SUM (Amount) -- Aggregate the Amount column using SUM
None.gif
FOR [ Quarter ] -- Pivot the Quarter column into column headings
None.gif
IN (Q1, Q2, Q3, Q4)) -- use these quarters
None.gif
AS P
None.gif GO
None.gif
None.gif select * into temp1 from orders
None.gifpivot ( sum(quantity) for product in ( [ Bike ], [ Chain ])) as a
None.gif
None.gif select * from temp1
None.gif
None.gif select customer, product,quantity
None.giffroam temp1
None.gifunpivot(quantity for product in ( [ Bike ], [ Chain ])) as a
None.gif九、ddl触发器
None.gif use demo
None.gif go
None.gif CREATE TRIGGER prevent_drop_table ON DATABASE FOR DROP_TABLE
None.gif AS
None.gif RAISERROR( ' Not allowed to drop tables. ', 10, 1)
None.gif PRINT ' DROP TABLE attempt in database ' + DB_NAME() + ' . '
None.gif PRINT CONVERT ( nvarchar ( 1000),EventData())
None.gif ROLLBACK
None.gif GO
None.gif -- test
None.gif
CREATE TABLE TestDROP(col1 INT)
None.gif go
None.gif INSERT INTO TestDROP VALUES( 1)
None.gif
None.gif drop talbe testdrop
None.gif
None.gif -- Server
None.gif
CREATE TRIGGER audit_ddl_logins ON ALL SERVER
None.gif FOR CREATE_LOGIN, ALTER_LOGIN, DROP_LOGIN
None.gif AS
None.gif PRINT ' DDL LOGIN took place. '
None.gif PRINT CONVERT ( nvarchar ( 1000),EventData())
None.gif GO
None.gif
None.gif -- test
None.gif
CREATE LOGIN login1 WITH PASSWORD = ' 123 '
None.gif ALTER LOGIN login1 WITH PASSWORD = ' xyz '
None.gif DROP LOGIN login1
None.gif丰富的数据类型 Richer Data Types
None.gif
None.gif 1varchar( max)、 nvarchar( max)和varbinary( max)数据类型最多可以保存2GB的数据,可以取代text、ntext或image数据类型。
None.gif CREATE TABLE myTable
None.gif(
None.gif id INT,
None.gif content VARCHAR( MAX)
None.gif)
None.gif
None.gif 2、XML数据类型
None.gifXML数据类型允许用户在SQL Server数据库中保存XML片段或文档。
None.gif
None.gif错误处理 Error Handling
None.gif
None.gif 1、新的异常处理结构
None.gif
None.gif 2、可以捕获和处理过去会导致批处理终止的错误
None.gif前提是这些错误不会导致连接中断(通常是严重程度为21以上的错误,例如,表或数据库完整性可疑、硬件错误等等。)。
None.gif
None.gif 3、TRY /CATCH 构造
None.gif SET XACT_ABORT ON
None.gif BEGIN TRY
None.gif <core logic >
None.gif END TRY
None.gif BEGIN CATCH TRAN_ABORT
None.gif <exception handling logic >
None.gif END TRY
None.gif
None.gif @@error may be quired as first statement in CATCH block
None.gif
None.gif 4、演示代码
None.gif USE demo
None.gif GO
None.gif -- 创建工作表
None.gif

None.gif CREATE TABLE student
None.gif (
None.gif stuid INT NOT NULL PRIMARY KEY,
None.gif stuname VARCHAR( 50)
None.gif )
None.gif
None.gif CREATE TABLE score
None.gif (
None.gif stuid INT NOT NULL REFERENCES student(stuid),
None.gif score INT
None.gif )
None.gif GO
None.gif
None.gif INSERT INTO student VALUES ( 101, ' zhangsan ')
None.gif INSERT INTO student VALUES ( 102, ' wangwu ')
None.gif INSERT INTO student VALUES ( 103, ' lishi ')
None.gif INSERT INTO student VALUES ( 104, ' maliu ')
None.gif
None.gif -- 调用一个运行时错误
None.gif
SET XACT_ABORT OFF
None.gif BEGIN TRAN
None.gif INSERT INTO score VALUES ( 101, 90)
None.gif INSERT INTO score VALUES ( 102, 78)
ExpandedBlockStart.gif ContractedBlock.gif INSERT INTO score VALUES ( 107, 76) /**/ /* 外键错误 */
None.gif INSERT INTO score VALUES ( 103, 81)
None.gif INSERT INTO score VALUES ( 104, 65)
None.gif COMMIT TRAN
None.gif GO
None.gif
None.gif SELECT * FROM student
None.gif SELECT * FROM score
None.gif
None.gif -- 使用TRYdot.gifCATCH构造,并调用一个运行时错误
None.gif
SET XACT_ABORT OFF
None.gif BEGIN TRY
None.gif BEGIN TRAN
None.gif INSERT INTO score VALUES ( 101, 90)
None.gif INSERT INTO score VALUES ( 102, 78)
ExpandedBlockStart.gif ContractedBlock.gif INSERT INTO score VALUES ( 107, 76) /**/ /* 外键错误 */
None.gif INSERT INTO score VALUES ( 103, 81)
None.gif INSERT INTO score VALUES ( 104, 65)
None.gif COMMIT TRAN
None.gif PRINT ' 事务提交 '
None.gif END TRY
None.gif BEGIN CATCH
None.gif ROLLBACK
None.gif PRINT ' 事务回滚 '
None.gif SELECT ERROR_NUMBER() AS ErrorNumber,
None.gif ERROR_SEVERITY() AS ErrorSeverity,
None.gif ERROR_STATE() as ErrorState,
None.gif ERROR_MESSAGE() as ErrorMessage;
None.gif END CATCH
None.gif GO
None.gif
None.gif SELECT * FROM score
None.gif GO
None.gif
None.gif快照隔离 Snapshot Isolation
None.gif
None.gif 1、写入程序不会阻碍读取程序
None.gif 2、Snapshot isolation must be enabled for DB
None.gif ALTER DATABASE 数据库 SET allow_snapshot_isolation ON
None.gif 3、Snapshot isolation must be enabled for connection
None.gif Set transaction isolation level snapshot
None.gif 4UPDATE transactions keep old versions of data in a linked list
None.gif 5、新的隔离级别提供了以下优点:
None.gif  1) 提高了只读应用程序的数据可用性
None.gif  2) 允许在OLTP环境中执行非阻止读取操作
None.gif  3) 可对写入事务进行自动的强制冲突检测
None.gif 6、演示代码
None.gif CREATE DATABASE demo2
None.gif GO
None.gif USE demo2
None.gif ALTER DATABASE demo2 SET allow_snapshot_isolation ON
None.gif CREATE TABLE test
None.gif (
None.gif tid INT NOT NULL primary key,
None.gif tname VARCHAR( 50) NOT NULL
None.gif )
None.gif INSERT INTO test VALUES( 1, ' version1 ')
None.gif INSERT INTO test VALUES( 2, ' version2 ')
None.gif
None.gif -- 连接一
None.gif

None.gif USE demo2
None.gif BEGIN TRAN
None.gif UPDATE test SET tname = ' version3 ' WHERE tid = 2
None.gif SELECT * FROM test
None.gif
None.gif -- 连接二
None.gif
USE demo2
None.gif SET transaction isolation level snapshot
None.gif SELECT * FROM test
None.gif
None.gif TOP 增强功能
None.gif
None.gif 1TOP 增强
None.gif可以指定一个数字表达式,以返回要通过查询影响的行数或百分比,还可以根据情况使用变量或子查询。
None.gif可以在DELETE、UPDATE和INSERT查询中使用TOP选项。
None.gif
None.gif 2、更好地替换SET ROWCOUNT选项,使之更为有效。
None.gif
None.gifOUTPUT
None.gif
None.gif 1、SQL Server 2005引入一个新的OUTPUT子句,以使您可以冲修改语句( INSERTUPDATEDELETE)中将数据返回到表变量中。
None.gif
None.gif 2、新的OUTPUT子局的语法为:
None.gifOUTPUT <dml_select_list > INTO @table_variable
None.gif可以通过引用插入的表或删除的表来访问被修改的行的旧 /新影象,其方式与访问触发器类似。在INSERT语句中,只能访问插入的表。在DELETE语句中,只能访问删除的表。在UPDATE语句中,可以访问插入的表和删除的表。
None.gif
None.gif 3、代码演示
None.gif USE demo
None.gif GO
None.gif CREATE TABLE tt
None.gif(
None.gif id INT IDENTITY,
None.gif c1 VARCHAR( 15)
None.gif)
None.gif GO
None.gif
None.gif INSERT INTO tt VALUES ( ' r1 ')
None.gif INSERT INTO tt VALUES ( ' r2 ')
None.gif INSERT INTO tt VALUES ( ' r5 ')
None.gif INSERT INTO tt VALUES ( ' r6 ')
None.gif INSERT INTO tt VALUES ( ' r7 ')
None.gif INSERT INTO tt VALUES ( ' r8 ')
None.gif INSERT INTO tt VALUES ( ' r9 ')
None.gif INSERT INTO tt VALUES ( ' r10 ')
None.gif
None.gif DECLARE @del AS TABLE (deletedId INT, deletedValue VARCHAR( 15))
None.gif DELETE tt
None.gifOUTPUT DELETED.id, DELETED.c1 INTO @del
None.gif WHERE id < 3
None.gif SELECT * FROM @del
None.gif GO
None.gif -- ---------------------------------------------
None.gif
USE demo
None.gif GO
None.gif CREATE TABLE toptest (column1 VARCHAR( 150))
None.gif GO
None.gif INSERT INTO toptest VALUES( ' t1 ')
None.gif INSERT INTO toptest VALUES( ' t2 ')
None.gif INSERT INTO toptest VALUES( ' t3 ')
None.gif INSERT INTO toptest VALUES( ' t4 ')
None.gif INSERT INTO toptest VALUES( ' t5 ')
None.gif INSERT INTO toptest VALUES( ' t6 ')
None.gif INSERT INTO toptest VALUES( ' t7 ')
None.gif INSERT INTO toptest VALUES( ' t8 ')
None.gif SELECT * FROM toptest
None.gif GO
None.gif
None.gif CREATE TABLE toptest2 (column2 VARCHAR( 150))
None.gif GO
None.gif INSERT INTO toptest2 VALUES( ' c1 ')
None.gif INSERT INTO toptest2 VALUES( ' c2 ')
None.gif
None.gif -- 声明3个变量
None.gif
DECLARE @a INT
None.gif DECLARE @b INT
None.gif DECLARE @c INT
None.gif
None.gif -- 赋值
None.gif
SET @a = 10
None.gif SET @b = 5
None.gif SELECT @c = @a / @b
None.gif
None.gif -- 使用计算表达式
None.gif
SELECT TOP( @c) * FROM toptest
None.gif
None.gif -- 使用SELECT语句作为条件
None.gif
SELECT TOP( SELECT COUNT( *) FROM toptest2) *
None.gif FROM toptest
None.gif
None.gif -- 指出top
None.gif
DELETE TOP( 2) toptest where column1 > ' t6 '
None.gif
None.gif -- 更新top
None.gif
UPDATE TOP( 2) toptest SET column1 = ' hi ' where column1 <= ' t2 '
None.gif
None.gif SELECT * FROM toptest
None.gif
None.gif排序函数 Ranking Functions
None.gif
None.gif 1、SQL Server引入几个新的排序函数:如ROW_NUMBER、RANK、DENSE_RANK等。这些新函数使您可以有效地分析数据以及向查询的结果行提供排序值。
None.gif
None.gif 2、排序函数都遵循类似的语法模式:
None.gif() OVER
None.gif( [ PARTITION BY ]
None.gif ORDER BY)
None.gif该函数只能在查询的两个子句中指定 - 在SELECT子句或ORDER BY子句中。以下详细讨论不同的函数。
None.gif
None.gif 3、ROW_NUMBER
None.gifROW_NUMBER是结果集的顺序, 而不是数据库中纪录存放的原始顺序
None.gif USE demo
None.gif GO
None.gif CREATE TABLE rankorder
None.gif(
None.gif orderid INT,
None.gif qty INT
None.gif)
None.gif GO
None.gif INSERT rankorder VALUES( 30001, 10)
None.gif INSERT rankorder VALUES( 10001, 10)
None.gif INSERT rankorder VALUES( 10006, 10)
None.gif INSERT rankorder VALUES( 40005, 10)
None.gif INSERT rankorder VALUES( 30003, 15)
None.gif INSERT rankorder VALUES( 30004, 20)
None.gif INSERT rankorder VALUES( 20002, 20)
None.gif INSERT rankorder VALUES( 20001, 20)
None.gif INSERT rankorder VALUES( 10005, 30)
None.gif INSERT rankorder VALUES( 30007, 30)
None.gif INSERT rankorder VALUES( 40001, 40)
None.gif GO
None.gif SELECT orderid,qty,
None.gif ROW_NUMBER() OVER( ORDER BY qty) AS rownumber,
None.gif RANK() OVER( ORDER BY qty) AS rank,
None.gif DENSE_RANK() OVER( ORDER BY qty) AS denserank
None.gif FROM rankorder
None.gif ORDER BY qty
None.gif
None.gif通用表表达式 Common Table Expressions
None.gif
None.gif通用表表达式(CTE)是一个可以由定义语句引用的临时表命名的结果集。在他们的简单形式中,您可以将CTE视为类似于视图和派生表混合功能的改进版本。在查询的FROM子句中引用CTE的方式类似于引用派生表和视图的方式。只须定义CTE一次,即可在查询中多次引用它。在CTE的定义中,可以引用在同一批处理中定义的变量。但是CTE的真正威力在于它们的递归功能,即CTE可以包含对它们自身的引用。
None.gif
None.gif视图、派生表和CTE内部的查询的一般形式
None.gif
None.gif 1、视图
None.gif CREATE VIEW <view_name >( <column_aliases >) AS <view_query >
None.gif
None.gif 2、派生表
None.gif SELECT * FROM ( <derived_table)query >) AS <dericed_table_alias >( <column_aliases >)
None.gif
None.gif 3、CTE
None.gif WITH <cte_alias >( <column_aliases >)
None.gif AS
None.gif{
None.gif <cte_query >
None.gif)
None.gif SELECT * FROM <cte_alias] >
None.gif在关键字WITH之后,为CTE提供一个别名,并且为它的结果列提供一个可选的别名列表;编写CTE的主体;然后从外部查询中引用它。
None.gif
None.gif 4、演示代码
None.gif USE AdventureWorks
None.gif GO
None.gif WITH SalesCTE(ProductID, SalesOrderID)
None.gif AS
None.gif(
None.gif SELECT ProductID, COUNT(SalesOrderID)
None.gif FROM Sales.SalesOrderDetail
None.gif GROUP BY ProductID
None.gif)
None.gif SELECT * FROM SalesCTE
None.gif
None.gifRecursive CTEs 递归的通用表表达式
None.gif
None.gif递归的CTE是根据至少两个查询(或者称为两个成员)构建的,一个是非递归查询,也成为固定成员,只能调用一次,另外一个是递归查询,也成为递归成员(RM),可以反复调用,直到查询不再返回行。查询由UNION ALL运算符连接为一个单独的CTE。
None.gif
None.gif -- 使用递归的通用表表达式
None.gif
USE demo
None.gif GO
None.gif CREATE TABLE CarParts
None.gif(
None.gif CarID INT NOT NULL,
None.gif Part VARCHAR( 15),
None.gif SubPart VARCHAR( 15),
None.gif Qty INT
None.gif)
None.gif GO
None.gif INSERT CarParts VALUES ( 1, ' Body ', ' Door ', 4)
None.gif INSERT CarParts VALUES ( 1, ' Body ', ' Trunk Lid ', 1)
None.gif INSERT CarParts VALUES ( 1, ' Body ', ' Car Hood ', 1)
None.gif INSERT CarParts VALUES ( 1, ' Door ', ' Handle ', 1)
None.gif INSERT CarParts VALUES ( 1, ' Door ', ' Lock ', 1)
None.gif INSERT CarParts VALUES ( 1, ' Door ', ' Window ', 1)
None.gif INSERT CarParts VALUES ( 1, ' Body ', ' Rivets ', 1000)
None.gif INSERT CarParts VALUES ( 1, ' Door ', ' Rivets ', 100)
None.gif INSERT CarParts VALUES ( 1, ' Door ', ' Mirror ', 1)
None.gif GO
None.gif SELECT * FROM CarParts
None.gif GO
None.gif
None.gif WITH CarPartsCTE(SubPart, Qty)
None.gif AS
None.gif(
None.gif -- 固定成员 (AM):
None.gif
-- SELECT查询无需参考CarPartsCTE
None.gif
SELECT SubPart, Qty
None.gif FROM CarParts
None.gif WHERE Part = ' Body '
None.gif UNION ALL
None.gif -- 递归成员 (RM):
None.gif
-- SELECT查询参考CarPartsCTE
None.gif
SELECT CarParts.SubPart, CarPartsCTE.Qty * CarParts.Qty
None.gif FROM CarPartsCTE
None.gif INNER JOIN CarParts ON CarPartsCTE.SubPart = CarParts.Part
None.gif WHERE CarParts.CarID = 1
None.gif)
None.gif -- 外部查询
None.gif
SELECT SubPart, SUM(Qty) AS TotalNUM
None.gif FROM CarPartsCTE
None.gif GROUP BY SubPart
None.gif
None.gif新的关系运算符 PIVOT /UNPIVOT /APPLY
None.gif
None.gif 1、PIVOT
None.gifPIVOT运算符将行旋转为列,并且可能同时执行聚合。使用PIVOT运算符时要注意的重要一点是,需要为它提供一个查询表达式,表达式使用视图、派生表或者是CTE只返回所关注的列。
None.gif
None.gif 2、UNPIVOT
None.gifUNPIVOT运算符执行与PIVOT运算符相反的操作;他将列旋转为行了。
None.gif
None.gif 3、APPLY
None.gifAPPLY关系运算符允许您对外部表的每个行调用指定的表值函数一次。您可以在查询的FROM子句中指定APPLY,其方式与使用JOIN关系运算符类似。APPLY具有两种形式: CROSS APPLY和OUTER APPLY。
None.gif
None.gif演示:
None.gif
None.gif USE demo
None.gif GO
None.gif
None.gif CREATE TABLE orders
None.gif(
None.gif Customer VARCHAR( 10) NOT NULL,
None.gif product VARCHAR( 20) NOT NULL,
None.gif quantity INT NOT NULL
None.gif)
None.gif GO
None.gif INSERT orders VALUES( ' Mike ', ' Bike ', 3)
None.gif INSERT orders VALUES( ' Mike ', ' Chain ', 2)
None.gif INSERT orders VALUES( ' Mike ', ' Bike ', 5)
None.gif INSERT orders VALUES( ' Lisa ', ' Bike ', 3)
None.gif INSERT orders VALUES( ' Lisa ', ' Chain ', 3)
None.gif INSERT orders VALUES( ' Lisa ', ' Chain ', 4)
None.gif INSERT orders VALUES( ' Lisa ', ' Bike ', 2)
None.gif
None.gif SELECT * FROM orders
None.gif
None.gif SELECT * FROM orders
None.gifPIVOT ( SUM(quantity) FOR product IN ( [ Bike ], [ Chain ])) AS a
None.gif USE demo
None.gif GO
None.gif CREATE TABLE SALES1
None.gif(
None.gif [ Year ] INT,
None.gif Quarter CHAR( 2),
None.gif Amount FLOAT
None.gif)
None.gif GO
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q1 ', 80)
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q2 ', 70)
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q3 ', 55)
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q3 ', 110)
None.gif INSERT INTO SALES1 VALUES ( 2001, ' Q4 ', 90)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q1 ', 200)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q2 ', 150)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q2 ', 40)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q2 ', 60)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q3 ', 120)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q3 ', 110)
None.gif INSERT INTO SALES1 VALUES ( 2002, ' Q4 ', 180)
None.gif GO
None.gif
None.gif SELECT * FROM SALES1
None.gifPIVOT
None.gif( SUM (Amount) -- 使用SUM聚合数量列
None.gif
FOR [ Quarter ] -- PIVOT Quarter 列
None.gif
IN (Q1, Q2, Q3, Q4)) -- 使用季节
None.gif
AS P
None.gif GO
None.gif
None.gif SELECT * INTO temp1 FROM orders
None.gifPIVOT ( sum(quantity) FOR product IN ( [ Bike ], [ Chain ])) AS a
None.gif
None.gif SELECT * FROM temp1
None.gif
None.gif SELECT customer, product,quantity
None.gif FROM temp1
None.gifUNPIVOT(quantity FOR product IN ( [ Bike ], [ Chain ])) AS a
None.gif -- --------------------------------------------------
None.gif
USE demo
None.gif GO
None.gif CREATE TABLE Arrays
None.gif(
None.gif aid INT NOT NULL IDENTITY PRIMARY KEY,
None.gif array VARCHAR( 7999) NOT NULL
None.gif)
None.gif GO
None.gif INSERT INTO Arrays VALUES( '')
None.gif INSERT INTO Arrays VALUES( ' 10 ')
None.gif INSERT INTO Arrays VALUES( ' 20,40,30 ')
None.gif INSERT INTO Arrays VALUES( ' -1,-3,-5 ')
None.gif GO
None.gif CREATE FUNCTION function1( @arr AS VARCHAR( 7999))
None.gif RETURNS @t TABLE(pos INT NOT NULL, value INT NOT NULL)
None.gif AS
None.gif BEGIN
None.gif DECLARE @end AS INT, @start AS INT, @pos AS INT
None.gif SELECT @arr = @arr + ' , ', @pos = 1,
None.gif @start = 1, @end = CHARINDEX( ' , ', @arr, @start)
None.gif WHILE @end > 1
None.gif BEGIN
None.gif INSERT INTO @t VALUES( @pos, SUBSTRING( @arr, @start, @end - @start))
None.gif
None.gif SELECT @pos = @pos + 1,
None.gif @start = @end + 1, @end = CHARINDEX( ' , ', @arr, @start)
None.gif END
None.gif RETURN
None.gif END
None.gif
None.gif -- 测试
None.gif
SELECT * FROM function1( ' 200,400,300 ')
None.gif GO
None.gif
None.gif SELECT A.aid, F. *
None.gif FROM Arrays AS A
None.gif CROSS APPLY function1(array) AS F
None.gif GO
None.gif SELECT A.aid, F. *
None.gif FROM Arrays AS A
None.gif OUTER APPLY function1(array) AS F
None.gif GO
None.gif
None.gifDDL触发器 DDL Triggers
None.gif
None.gifSQL Server 2005可以就整个服务器或数据库的某个范围为DDL事件定义触发器。也可以为单个DDL语句(例如:CREAT_TABLE、DROP_TABLE等)或者为一组语句(例如:指定DDL_DATABASE_LEVEL_EVENTS想要触发器触发数据库所有DDL事件)定义DDL触发器。
None.gif
None.gif在DDL触发器内部,可以通过访问eventdata()函数获得与激发该触发器的事件有关的数据。该eventdata()函数返回有关事件的xml数据。
None.gif
None.gifDDL触发器特别有用的方案包括DDL更改的完整性检查、审核方案以及其他方案。
None.gif
None.gif代码演示:
None.gif
None.gif USE demo
None.gif GO
None.gif CREATE TRIGGER prevent_drop_table ON DATABASE FOR DROP_TABLE
None.gif AS
None.gif RAISERROR( ' 没有删除表的权限. ', 10, 1)
None.gif PRINT ' 尝试在数据库 ' + DB_NAME() + ' 中删除表. '
None.gif PRINT CONVERT ( nvarchar ( 1000),EventData())
None.gif ROLLBACK
None.gif GO
None.gif -- 测试
None.gif
CREATE TABLE TestDROP(col1 INT)
None.gif GO
None.gif INSERT INTO TestDROP VALUES( 1)
None.gif
None.gif DROP TABLE testdrop
None.gif
None.gif -- Server
None.gif
CREATE TRIGGER audit_ddl_logins ON ALL SERVER
None.gif FOR CREATE_LOGIN, ALTER_LOGIN, DROP_LOGIN
None.gif AS
None.gif PRINT ' 发生DDL LOGIN. '
None.gif PRINT CONVERT ( nvarchar ( 1000),EventData())
None.gif GO
None.gif
None.gif -- 测试
None.gif
CREATE LOGIN login1 WITH PASSWORD = ' 123 '
None.gif ALTER LOGIN login1 WITH PASSWORD = ' xyz '
None.gif DROP LOGIN login1
None.gifSQL Server 2005 在Transaction -SQL上所做的改进反映了其更好地满足了ANSI - 99 SQL规范的要求以及客户的需求。
None.gif
None.gif
None.gif create proc [ dbo ]. [ Name_Add ]
None.gif @Name varchar( 50)
None.gif as
None.gif begin
None.gif
None.gif begin tran
None.gif insert Names (Name)
None.gif select ( @Name) where not exists ( select NameId from Names with( HOLDLOCK) where Name = @Name)
None.gif commit tran
None.gif
None.gif select NameId,Name from Names with(nolock) where Name = @Name
None.gif end
None.gif
None.gif 要点:检查,加锁,插入值在一句sql中完成.这样再大的并发也不怕了.
None.gif



本文转自高海东博客园博客,原文链接:http://www.cnblogs.com/ghd258/archive/2005/10/19/257914.html,如需转载请自行联系原作者
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
7天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
45 10
|
17天前
|
SQL
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
15 0
|
7天前
|
SQL 算法 数据库
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
61 6
|
7天前
|
SQL 存储 数据挖掘
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
服务器数据恢复环境: 一台安装windows server操作系统的服务器。一组由8块硬盘组建的RAID5,划分LUN供这台服务器使用。 在windows服务器内装有SqlServer数据库。存储空间LUN划分了两个逻辑分区。 服务器故障&初检: 由于未知原因,Sql Server数据库文件丢失,丢失数据涉及到3个库,表的数量有3000左右。数据库文件丢失原因还没有查清楚,也不能确定数据存储位置。 数据库文件丢失后服务器仍处于开机状态,所幸没有大量数据写入。 将raid5中所有磁盘编号后取出,经过硬件工程师检测,没有发现明显的硬件故障。以只读方式将所有磁盘进行扇区级的全盘镜像,镜像完成后将所
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
|
11天前
|
SQL 安全 Java
SQL server 2017安装教程
SQL server 2017安装教程
14 1
|
24天前
|
SQL 存储 Python
Microsoft SQL Server 编写汉字转拼音函数
Microsoft SQL Server 编写汉字转拼音函数
|
1月前
|
SQL 存储 数据库
数据安全无忧,SQL Server 2014数据库定时备份解密
数据安全无忧,SQL Server 2014数据库定时备份解密
|
1月前
|
SQL 网络协议 Windows
破解SQL Server迷局,彻底解决“管道的另一端无任何进程错误233”
破解SQL Server迷局,彻底解决“管道的另一端无任何进程错误233”
|
1月前
|
SQL 数据库 数据安全/隐私保护
Sql Server数据库Sa密码如何修改
Sql Server数据库Sa密码如何修改
|
2月前
|
SQL 算法 数据库
【数据库SQL server】关系数据库标准语言SQL之数据查询
【数据库SQL server】关系数据库标准语言SQL之数据查询
95 0