•
检查存在性:@x.exist (xquery string) 返回位
•
返回标量值 @x.value (xquery string, sql_type string) 返回 sql_type
XQuery 提供了以下修改方法:@x.modify (xDML string)。
作为示例,一个名为 Jobs 的表在一个名为 jobinfo 的列中包含 XML 格式的作业信息。以下查询在执行一些操作之后返回每个符合某个条件的行的 ID 和 XML 数据。在 WHERE 子句中调用方法 jobinfo.exist() 以筛选所需的行。对于在 jobinfo 列中包含被编辑的元素且该元素的 date 属性大于 Transact-SQL 变量 @date 的行,它只返回 1。对于所返回的每个行,通过调用 jobinfo.query() 方法生成 XML 结果。对于在 jobinfo 中找到的每个作业元素,query() 方法生成一个 jobschedule 元素(它的 id 属性基于该作业的 id 属性)以及 begin 和 end 子元素(它们的数据基于 jobinfo 中的 start 和 end 属性):
SELECT id, jobinfo.query( 'for $j in //job return <jobschedule id="{$j/@id}"> <begin>{data($j/@start)}</begin> <end>{data($j/@end)}</end> </jobschedule>') FROM Jobs WHERE 1 = jobinfo.exist( '//edited[@date > sql:variable("@date")]')
以下 value()
方法调用以 Transact-SQL datetime 格式返回 jobinfo 中的第一个作业的 start 属性:
SELECT id, jobinfo.value('(//job)[1]/@start', 'DATETIME') AS startdt FROM Jobs WHERE id = 1
XQuery 还可以用来修改数据。例如,可以使用以下代码为雇员 1 更新 Employees 表中的 empinfo XML 列。将 resume 元素的被编辑的子元素的 date 属性更新为新的值:
UPDATE Employees SET empinfo.modify( 'update /resume/edited/@date to xs:date("2000-6-20")') WHERE empid = 1
DDL 触发器在较低版本的 SQL Server 中,只能为针对表发出的 DML 语句(INSERT、UPDATE 和 DELETE)定义 AFTER 触发器。SQL Server 2005 Beta 2 使您可以就整个服务器或数据库的某个范围为 DDL 事件定义触发器。您可以为单个 DDL 语句(例如,CREATE_TABLE)或者为一组语句(例如,DDL_DATABASE_LEVEL_EVENTS)定义 DDL 触发器。在该触发器内部,您可以通过访问 eventdata() 函数获得与激发该触发器的事件有关的数据。该函数返回有关事件的 XML 数据。每个事件的架构都继承了 Server Events 基础架构。
事件信息包括:
•
事件何时发生。
•
事件是从哪个 SPID 中发出的。
•
事件的类型。
•
受影响的对象。
•
SET 选项。
•
激发它的 Transact-SQL 语句。
与较低版本的 SQL Server 中的触发器类似,DDL 触发器在激发它们的事务的上下文中运行。如果您决定撤消激发触发器的事件,则可以发出一个 ROLLBACK 语句。例如,以下触发器可防止在当前数据库中创建新表:
CREATE TRIGGER trg_capture_create_table ON DATABASE FOR CREATE_TABLE AS -- PRINT event information For DEBUG PRINT 'CREATE TABLE Issued' PRINT EventData() -- Can investigate data returned by EventData() and react accordingly. RAISERROR('New tables cannot be created in this database.', 16, 1) ROLLBACK GO
如果您在创建了该触发器的数据库中发出 CREATE TABLE 语句,则应当获得以下输出:
CREATE TABLE T1(col1 INT) CREATE TABLE Issued <EVENT_INSTANCE> <PostTime>2003-04-17T13:55:47.093</PostTime> <SPID>53</SPID> <EventType>CREATE_TABLE</EventType> <Database>testdb</Database> <Schema>dbo</Schema> <Object>T1</Object> <ObjectType>TABLE</ObjectType> <TSQLCommand> <SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" /> <CommandText>CREATE TABLE T1(col1 INT)</CommandText> </TSQLCommand> </EVENT_INSTANCE> .Net SqlClient Data Provider: Msg 50000, Level 16, State 1, Procedure trg_capture_create_table, Line 10 New tables cannot be created in this database. .Net SqlClient Data Provider: Msg 3609, Level 16, State 1, Line 1 Transaction ended in trigger. Batch has been aborted.
请注意,本文对 XML 输出进行了手动格式化,以便提高可读性。当您运行该代码时,会获得未经格式化的 XML 输出。
要删除该触发器,请发出以下语句:
DROP TRIGGER trg_capture_create_table ON DATABASE
DDL 触发器特别有用的方案包括 DDL 更改的完整性检查、审核方案以及其他方案。作为 DDL 完整性增强的示例,以下数据库级别触发器拒绝了创建不带主键的表的企图:
CREATE TRIGGER trg_create_table_with_pk ON DATABASE FOR CREATE_TABLE AS DECLARE @eventdata AS XML, @objectname AS NVARCHAR(257), @msg AS NVARCHAR(500) SET @eventdata = eventdata() SET @objectname = N'[' + CAST(@eventdata.query('data(//SchemaName)') AS SYSNAME) + N'].[' + CAST(@eventdata.query('data(//ObjectName)') AS SYSNAME) + N']' IF OBJECTPROPERTY(OBJECT_ID(@objectname), 'TableHasPrimaryKey') = 0 BEGIN SET @msg = N'Table ' + @objectname + ' does not contain a primary key.' + CHAR(10) + N'Table creation rolled back.' RAISERROR(@msg, 16, 1) ROLLBACK RETURN END
当 CREATE TABLE 语句发出时,该触发器被激发。该触发器使用 XQuery






