程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> SQL Server 2008 對 T-SQL 語言的增強

SQL Server 2008 對 T-SQL 語言的增強

編輯:關於SqlServer
 Microsoft SQL Server 2008 對 T-SQL 語言進行了進一步增強。為了讓開發人員盡快了解這些變化,我們針對 2007 年 6 月 CTP 版本的 SQL Server 2008 中的 T-SQL 語言的新增功能進行了分析和嘗試。本文描述自 SQL Server 2008 CTP1 以來這些語言增強和變化。

  本文包含如下內容:

  · T-SQL 行構造器

  · FORCESEEK 表提示

  · GROUPING SETS

  · 兼容性級別

  · 用戶自定義表數據類型

  · 表值參數

  · MERGE 語句

  本文適用於:Microsoft)R) SQL Server(TM) 2008 Developer Edition June 2007 CTP

  1、T-SQL 行構造器

  T-SQL 行構造器(Row Constructors)用來在 INSERT 語句中一次性插入多行數據。例如:

CREATE TABLE #a
(
  Column1 nvarchar(max),
  Column2 nvarchar(max)
);
GO
INSERT INTO #a
VALUES (
('1', '1'),
('2', '2')
);
SELECT * FROM #a;
GO
DROP TABLE #a;
GO

  經過增強後的 INSERT 語句的語法結構如下。

[ WITH <common_table_expression> [ ,...n ] ]
INSERT
  [ TOP ( expression ) [ PERCENT ] ]
  [ INTO ]
  { <object> | rowset_function_limited
   [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
  }
{
  [ ( column_list ) ]
  [ <OUTPUT Clause> ]
  { VALUES ( ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n ] )
  | derived_table
  | execute_statement
  | <dml_table_source>
  | DEFAULT VALUES
  }
}
[; ]
<object> ::=
{
  [ server_name . database_name . schema_name .
   | database_name .[ schema_name ] .
   | schema_name .
  ]
    table_or_vIEw_name
}
<dml_table_source> ::=
  SELECT <select_list>
  FROM ( <dml_statement_with_output_clause> )
           [AS] table_alias [ ( column_alias [ ,...n ] ) ]
    [ WHERE <search_condition> ]
  [ OPTION ( <query_hint> [ ,...n ] ) ]

  2. FORCESEEK 提示

  FORCESEEK 是一個新的表提示(Table Hints),它用來指定 SQL Server 查詢優化程序如何更高效的執行查詢。該提示指示優化程序對查詢引用的表和視圖通過索引檢索來作為唯一的查詢執行訪問路徑。也就是強制通過索引檢索數據。例如:

USE tempdb;
GO
DROP TABLE t;
GO
CREATE TABLE t(i int UNIQUE, j int, vc varchar(100));
CREATE INDEX t_vc ON t(vc);
GO
DECLARE @p1 int, @p2 int, @p3 int, @p4 int, @p5 int;
SELECT * FROM t WHERE i IN (@p1, @p2, @p3, @p4, @p5);
GO
DECLARE @p1 int, @p2 int, @p3 int, @p4 int, @p5 int;
SELECT * FROM t WITH (FORCESEEK) WHERE i IN (@p1, @p2, @p3, @p4, @p5);
GO
SELECT * FROM t WHERE vc LIKE 'Test%';
GO
SELECT * FROM t WITH (FORCESEEK) WHERE vc LIKE 'Test%';
GO
DECLARE @vc varchar(100);
SELECT * FROM t WHERE vc LIKE @vc;
GO
DECLARE @vc varchar(100);
SELECT * FROM t WITH (FORCESEEK) where vc like @vc;
GO

  3. GROUPING SETS

  新的 T-SQL 對 GROUP BY 子句增加了 GROUPING SETS, ROLLUP 和 CUBE 操作符。還有一個新的函數 GROUPING_ID(),它相比 GROUPING() 函數返回更多分組級別的信息。WITH ROLLUP, WITH CUBE 和 ALL 等非 ISO 標准語法已經不再有效。

  4. 兼容性級別

  新的 ALTER DATABASE SET COMPATIBILITY_LEVEL 語法替換了 sp_dbcomplevel 存儲過程。它用來設置特定數據庫的兼容性級別。其語法形式為:

ALTER DATABASE database_name
SET COMPATIBILITY_LEVEL = { 80 | 90 | 100 }

  您可以為 database_name 為名稱的數據庫設置特定兼容性級別。80、90 和 100 分別代表 SQL Server 2000、SQL Server 2005 和 SQL Server 2008。

  5. 用戶自定義表數據類型

  現在,SQL Server 提供一種新的用戶自定義數據類型——自定義表數據類型(User-defined Table Types)。它可以作為參數提供給語句、存儲過程或者函數。您還可以為它創建唯一約束和主鍵。

  請使用 CREATE TYPE 語句創建這種數據類型。如:

USE AdventureWorks;
GO
/* Create a user-defined table type */
CREATE TYPE LocationTableType AS TABLE
( LocationName VARCHAR(50)
, CostRate INT );
GO

  對於表類型,有如下約束:

  1、用戶自定義表類型不能作為表的列或者結構化用戶自定義類型的域。

  2、基於用戶自定義表類型的別名類型。

  3、不允許 NOT FOR REPLICATION 選項。

  4、CHECK 約束需要一個計算列。

  5、在計算列上的主鍵必須包含 NOT NULL 和 PERSISTED 約束。

  6、不能在用戶自定義表類型上創建非簇索引。除非索引是創建 PRIMARY KEY 或 UNIQUE 約束的返回值。

  7、不能指定 DEFAULT 值。

  8、一旦用戶自定義表類型被創建,則它就無法更改。

  9、如果沒有定義用戶自定義表類型上的計算列,則用戶自定義函數無法調用。

  6. 表值參數

  數據庫引擎現在支持一種新的參數類型來引用用戶自定義表類型(參考 5)。表值參數可以發送更多的 SQL Server 數據。

  下面的示例展示了如何使用表值參數。

USE AdventureWorks;
GO
/* Create a table type. */
CREATE TYPE LocationTableType AS TABLE
( LocationName VARCHAR(50)
, CostRate INT );
GO
/* Create a procedure to receive data for the table-valued parameter. */
CREATE PROCEDURE usp_InsertProductionLocation
  @TVP LocationTableType READONLY
  AS
  SET NOCOUNT ON
  INSERT INTO [AdventureWorks].[Production].[Location]
      ([Name]
      ,[CostRate]
      ,[Availability]
      ,[ModifIEdDate])
    SELECT *, 0, GETDATE()
    FROM @TVP;
    GO
/* Declare a variable that references the type. */
DECLARE @LocationTVP
AS LocationTableType;
/* Add data to the table variable. */
INSERT INTO @LocationTVP (LocationName, CostRate)
  SELECT [Name], 0.00
  FROM
  [AdventureWorks].[Person].[StateProvince];
/* Pass the table variable data to a stored procedure. */
EXEC usp_InsertProductionLocation @LocationTVP;
GO

  7. MERGE 語句

  這個新增的 Transaction SQL 語句在一個基於源數據連接結果集的目標表上執行 INSERT、UPDATE 和 DELETE 操作。該語法允許您將一個數據源連接到目標表或視圖上。然後在連接後的結果集上執行多種操作。

  MERGE 的語法為:

[ WITH <common_table_expression> [,...n] ]
MERGE
[ TOP ( expression ) [ PERCENT ] ]
[ INTO ] target_table [ [ AS ] table_alias ]
    [ WITH ( <merge_hint> ) ]
USING <table_source>
ON <search_condition>
[ WHEN MATCHED [ AND <search_condition> ]
    THEN <merge_matched> ]
[ WHEN [TARGET] NOT MATCHED [ AND <search_condition> ]
    THEN <merge_not_matched> ]
[ WHEN SOURCE NOT MATCHED [ AND <search_condition> ]
    THEN <merge_ matched> ]
<output_clause>
[ OPTION ( <query_hint> [ ,...n ] ) ]  
;
<merge_hint>::=
    { [ <table_hint_limited> [ ,...n ] ]
  [ [ , ] INDEX ( index_val [ ,...n ] ) ] }
<table_source> ::=
{
    table_or_vIEw_name [ [ AS ] table_alias ] [ <tablesample_clause> ]
        [ WITH ( table_hint [ [ , ]...n ] ) ]
  | rowset_function [ [ AS ] table_alias ]
        [ ( bulk_column_alias [ ,...n ] ) ]
  | user_defined_function [ [ AS ] table_alias ]
  | OPENXML <openXML_clause>
  | derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ]
  | <joined_table>
  | <pivoted_table>
  | <unpivoted_table>
}
<merge_matched>::=
        { UPDATE SET <set_clause> | DELETE }
<set_clause>::=
  { column_name = { expression | DEFAULT | NULL }
 | { udt_column_name. { { property_name = expression
    | fIEld_name = expression }
    | method_name ( argument [ ,...n ] ) } }
 | column_name { .WRITE ( expression , @Offset , @Length ) }
 | @variable = expression
  } [ ,...n ]
<merge_not_matched>::=
    INSERT [ ( <column_list> ) ]
        { VALUES ( <values_list> )
       | DEFAULT VALUES }
<output_clause>::=
{
  [ OUTPUT <dml_select_list> INTO { @table_variable | output_table }
    [ (column_list) ] ]
    [ OUTPUT <dml_select_list> ]
}
<dml_select_list>::=
{ <column_name> | scalar_expression } [ [AS] column_alias_identifIEr ]
   [ ,...n ]
<column_name> ::=
  { DELETED | INSERTED | from_table_name } . { * | column_name }
  | $ACTION

  示例:在一條 SQL 語句中使用 WHERE 在一張表上執行 UPDATE 和 DELETE 操作

USE AdventureWorks;
GO
MERGE Production.ProductInventory AS pi
USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail sod
  JOIN Sales.SalesOrderHeader soh
  ON sod.SalesOrderID = soh.SalesOrderID
  AND soh.OrderDate = GETDATE()
  GROUP BY ProductID) AS src (ProductID, OrderQty)
ON (pi.ProductID = src.ProductID)
WHEN MATCHED AND pi.Quantity - src.OrderQty <> 0
  THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty
WHEN MATCHED AND pi.Quantity - src.OrderQty = 0
  THEN DELETE;

  這個示例是一個非常典型的銷售定貨庫存問題。這個示例很簡單,表達的意思就是:如果某一個產品產生了銷售定單數據,則

  將其對應的產品庫存除去該銷售定單所產生的數量,如果當前庫存數量與該銷售定單數量相同,則從庫存表中刪除該產品的庫存紀錄。

  我們看到,利用 MERGE 語句可以將復雜的 SQL 語句簡化。它比起 IF、CASE 等更加靈活和強大。

  結論

  Microsoft SQL Server 2008 對事務性 SQL 語言做了一些增強,提高了查詢效率。使得 SQl Server 成為大中型企業數據庫的首先產品。SQL Server 2008 將伴隨 Visual Studio 2008 一起發布,開發人員提前了解這些信息有助於在 SQL Server 的新版本發布後快速建立基於該版本的企業級應用程序。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved