SQLServer2005中的T-SQL增强

1、varchar(max)nvarchar(max)varbinary(max)数据型最多可以保存2GB的数据,可以取代textntextimage数据型。

CREATE TABLE  myTable
(
    id 
INT
,
    content 
VARCHAR(MAX
)
)

2XML数据
XML
数据型允SQL Server数据中保存XML片段或文档。

错误处 Error Handling

1、新的异常
2、可以捕去会致批止的错误
前提是错误不会接中断(通常是重程度21以上的错误,例如,表或数据完整性可疑、硬件错误等等。)。
3TRY/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 功能

1TOP
可以指定一个数字表达式,以返回要通过查询影响的行数或百分比,可以根据情况使用量或子查询
可以在DELETEUPDATEINSERT查询中使用TOP选项

2、更好地替SET ROWCOUNT选项,使之更有效。

OUTPUT

1SQL Server 2005引入一个新的OUTPUT子句,以使您可以冲修改(INSERTUPDATEDELETE)中将数据返回到表量中。

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

1SQL Server引入几个新的排序函数:如ROW_NUMBERRANKDENSE_RANK等。些新函数使您可以有效地分析数据以及向查询果行提供排序

2、排序函数都遵循似的法模式:

() OVER
(
[ PARTITION BY ]
ORDER   BY )

函数只能在查询的两个子句中指定 - SELECT子句或ORDER BY子句中。以下详细讨论不同的函数。 

3ROW_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 > )

3CTE

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

1PIVOT
PIVOT
运算符将行旋转为列,并且可能同时执行聚合。使用PIVOT运算符要注意的重要一点是,需要它提供一个查询表达式,表达式使用视图、派生表或者是CTE只返回所注的列。

2UNPIVOT
UNPIVOT
运算符行与PIVOT运算符相反的操作;他将列旋转为行了。

3APPLY
APPLY
系运算符允外部表的个行用指定的表函数一次。您可以在查询FROM子句中指定APPLY,其方式与使用JOIN系运算符似。APPLY具有两形式:CROSS APPLYOUTER 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_TABLEDROP_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功能提高了用查询时的表达能力,使用可以改善代的性能,并且充了错误处理能力。SQL Server 2005 Transaction-SQL上所做的改反映了其更好地足了ANSI-99 SQL范的要求以及客的需求。Transaction-SQL和托管代选择

 

你可能感兴趣的:(sqlserver2005)