技术开发 频道

SQL Server 2008 对 T-SQL 语言的增强

  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 的新版本发布后快速建立基于该版本的企业级应用程序。
0
相关文章