青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

山寨:不是最好的,是最適合我們的!歡迎體驗山寨 中文版MSDN

Blog @ Blog

當華美的葉片落盡,生命的脈絡才歷歷可見。 -- 聶魯達

常用鏈接

統計

積分與排名

BBS

Blog

Web

最新評論

SQL觸發器語法參考

語法
CREATE TRIGGER trigger_name 
ON { table | view } 
[ WITH ENCRYPTION ] 
{
    { { 
FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] }
        
[ WITH APPEND ]
        
[ NOT FOR REPLICATION ]
        
AS
        
[ { IF UPDATE ( column )
            [ { AND | OR } UPDATE ( column ) 
]
                
[ ]
        
| IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )
                { comparison_operator } column_bitmask 
[ ]
        } ] 
        sql_statement 
[ ] 
    } 


參數

trigger_name

是觸發器的名稱。觸發器名稱必須符合標識符規則,并且在數據庫中必須唯一??梢赃x擇是否指定觸發器所有者名稱。

Table | view

是在其上執行觸發器的表或視圖,有時稱為觸發器表或觸發器視圖??梢赃x擇是否指定表或視圖的所有者名稱。

WITH ENCRYPTION

加密 syscomments 表中包含 CREATE TRIGGER 語句文本的條目。使用 WITH ENCRYPTION 可防止將觸發器作為 SQL Server 復制的一部分發布。

AFTER

指定觸發器只有在觸發 SQL 語句中指定的所有操作都已成功執行后才激發。所有的引用級聯操作和約束檢查也必須成功完成后,才能執行此觸發器。

如果僅指定 FOR 關鍵字,則 AFTER 是默認設置。

不能在視圖上定義 AFTER 觸發器。

INSTEAD OF

指定執行觸發器而不是執行觸發 SQL 語句,從而替代觸發語句的操作。

在表或視圖上,每個 INSERT、UPDATE 或 DELETE 語句最多可以定義一個 INSTEAD OF 觸發器。然而,可以在每個具有 INSTEAD OF 觸發器的視圖上定義視圖。

INSTEAD OF 觸發器不能在 WITH CHECK OPTION 的可更新視圖上定義。如果向指定了 WITH CHECK OPTION 選項的可更新視圖添加 INSTEAD OF 觸發器,SQL Server 將產生一個錯誤。用戶必須用 ALTER VIEW 刪除該選項后才能定義 INSTEAD OF 觸發器。

{ [DELETE] [,] [INSERT] [,] [UPDATE] }

是指定在表或視圖上執行哪些數據修改語句時將激活觸發器的關鍵字。必須至少指定一個選項。在觸發器定義中允許使用以任意順序組合的這些關鍵字。如果指定的選項多于一個,需用逗號分隔這些選項。

對于 INSTEAD OF 觸發器,不允許在具有 ON DELETE 級聯操作引用關系的表上使用 DELETE 選項。同樣,也不允許在具有 ON UPDATE 級聯操作引用關系的表上使用 UPDATE 選項。

WITH APPEND

指定應該添加現有類型的其它觸發器。只有當兼容級別是 65 或更低時,才需要使用該可選子句。如果兼容級別是 70 或更高,則不必使用 WITH APPEND 子句添加現有類型的其它觸發器(這是兼容級別設置為 70 或更高的 CREATE TRIGGER 的默認行為)。有關更多信息,請參見 sp_dbcmptlevel

WITH APPEND 不能與 INSTEAD OF 觸發器一起使用,或者,如果顯式聲明 AFTER 觸發器,也不能使用該子句。只有當出于向后兼容而指定 FOR 時(沒有 INSTEAD OF 或 AFTER),才能使用 WITH APPEND。以后的版本將不支持 WITH APPEND 和 FOR(將被解釋為 AFTER)。

NOT FOR REPLICATION

表示當復制進程更改觸發器所涉及的表時,不應執行該觸發器。

AS

是觸發器要執行的操作。

sql_statement

是觸發器的條件和操作。觸發器條件指定其它準則,以確定 DELETE、INSERT 或 UPDATE 語句是否導致執行觸發器操作。

當嘗試 DELETE、INSERT 或 UPDATE 操作時,Transact-SQL語句中指定的觸發器操作將生效。

觸發器可以包含任意數量和種類的 Transact-SQL 語句。觸發器旨在根據數據修改語句檢查或更改數據;它不應將數據返回給用戶。觸發器中的 Transact-SQL 語句常常包含控制流語言。CREATE TRIGGER 語句中使用幾個特殊的表:

  • deletedinserted 是邏輯(概念)表。這些表在結構上類似于定義觸發器的表(也就是在其中嘗試用戶操作的表);這些表用于保存用戶操作可能更改的行的舊值或新值。例如,若要檢索 deleted 表中的所有值,請使用:
    SELECT *
        FROM deleted
        
  • 如果兼容級別等于 70,那么在 DELETE、INSERT 或 UPDATE 觸發器中,SQL Server 將不允許引用 inserteddeleted 表中的 text、ntextimage 列。不能訪問 inserteddeleted 表中的 textntextimage 值。若要在 INSERT 或 UPDATE 觸發器中檢索新值,請將 inserted 表與原始更新表聯接。當兼容級別是 65 或更低時,對 inserteddeleted 表中允許空值的textntextimage 列,將返回空值;如果這些列不可為空,則返回零長度字符串。

    當兼容級別是 80 或更高時,SQL Server 允許在表或視圖上通過 INSTEAD OF 觸發器更新 textntextimage 列。

n

是表示觸發器中可以包含多條 Transact-SQL 語句的占位符。對于 IF UPDATE (column) 語句,可以通過重復 UPDATE (column) 子句包含多列。

IF UPDATE (column)

測試在指定的列上進行的 INSERT 或 UPDATE 操作,不能用于 DELETE 操作??梢灾付ǘ嗔小R驗樵?ON 子句中指定了表名,所以在 IF UPDATE 子句中的列名前不要包含表名。若要測試在多個列上進行的 INSERT 或 UPDATE 操作,請在第一個操作后指定單獨的 UPDATE(column) 子句。在 INSERT 操作中 IF UPDATE 將返回 TRUE 值,因為這些列插入了顯式值或隱性 (NULL) 值。

說明  IF UPDATE (column) 子句的功能等同于 IF、IF...ELSE 或 WHILE 語句,并且可以使用 BEGIN...END 語句塊。有關更多信息,請參見控制流語言。

 

可以在觸發器主體中的任意位置使用 UPDATE (column)。

column

是要測試 INSERT 或 UPDATE 操作的列名。該列可以是 SQL Server 支持的任何數據類型。但是,計算列不能用于該環境中。有關更多信息,請參見數據類型。

IF (COLUMNS_UPDATED())

測試是否插入或更新了提及的列,僅用于 INSERT 或 UPDATE 觸發器中。COLUMNS_UPDATED 返回 varbinary 位模式,表示插入或更新了表中的哪些列。

COLUMNS_UPDATED 函數以從左到右的順序返回位,最左邊的為最不重要的位。最左邊的位表示表中的第一列;向右的下一位表示第二列,依此類推。如果在表上創建的觸發器包含 8 列以上,則 COLUMNS_UPDATED 返回多個字節,最左邊的為最不重要的字節。在 INSERT 操作中 COLUMNS_UPDATED 將對所有列返回 TRUE 值,因為這些列插入了顯式值或隱性 (NULL) 值。

可以在觸發器主體中的任意位置使用 COLUMNS_UPDATED。

bitwise_operator

是用于比較運算的位運算符。

updated_bitmask

是整型位掩碼,表示實際更新或插入的列。例如,表 t1 包含列 C1、C2、C3、C4C5。假定表 t1 上有 UPDATE 觸發器,若要檢查列 C2、C3 C4 是否都有更新,指定值 14;若要檢查是否只有列 C2 有更新,指定值 2。

comparison_operator

是比較運算符。使用等號 (=) 檢查 updated_bitmask 中指定的所有列是否都實際進行了更新。使用大于號 (>) 檢查 updated_bitmask 中指定的任一列或某些列是否已更新。

column_bitmask

是要檢查的列的整型位掩碼,用來檢查是否已更新或插入了這些列。

注釋

觸發器常常用于強制業務規則和數據完整性。SQL Server 通過表創建語句(ALTER TABLE 和 CREATE TABLE)提供聲明引用完整性 (DRI);但是 DRI 不提供數據庫間的引用完整性。若要強制引用完整性(有關表的主鍵和外鍵之間關系的規則),請使用主鍵和外鍵約束(ALTER TABLE 和 CREATE TABLE 的 PRIMARY KEY 和 FOREIGN KEY 關鍵字)。如果觸發器表存在約束,則在 INSTEAD OF 觸發器執行之后和 AFTER 觸發器執行之前檢查這些約束。如果違反了約束,則回滾 INSTEAD OF 觸發器操作且不執行(激發)AFTER 觸發器。

可用 sp_settriggerorder 指定表上第一個和最后一個執行的 AFTER 觸發器。在表上只能為每個 INSERT、UPDATE 和 DELETE 操作指定一個第一個執行和一個最后一個執行的 AFTER 觸發器。如果同一表上還有其它 AFTER 觸發器,則這些觸發器將以隨機順序執行。

如果 ALTER TRIGGER 語句更改了第一個或最后一個觸發器,則將除去已修改觸發器上設置的第一個或最后一個特性,而且必須用 sp_settriggerorder 重置排序值。

只有當觸發 SQL 語句(包括所有與更新或刪除的對象關聯的引用級聯操作和約束檢查)成功執行后,AFTER 觸發器才會執行。AFTER 觸發器檢查觸發語句的運行效果,以及所有由觸發語句引起的 UPDATE 和 DELETE 引用級聯操作的效果。

觸發器限制

CREATE TRIGGER 必須是批處理中的第一條語句,并且只能應用到一個表中。

觸發器只能在當前的數據庫中創建,不過觸發器可以引用當前數據庫的外部對象。

如果指定觸發器所有者名稱以限定觸發器,請以相同的方式限定表名。

在同一條 CREATE TRIGGER 語句中,可以為多種用戶操作(如 INSERT 和 UPDATE)定義相同的觸發器操作。

如果一個表的外鍵在 DELETE/UPDATE 操作上定義了級聯,則不能在該表上定義 INSTEAD OF DELETE/UPDATE 觸發器。

在觸發器內可以指定任意的 SET 語句。所選擇的 SET 選項在觸發器執行期間有效,并在觸發器執行完后恢復到以前的設置。

與使用存儲過程一樣,當觸發器激發時,將向調用應用程序返回結果。若要避免由于觸發器激發而向應用程序返回結果,請不要包含返回結果的 SELECT 語句,也不要包含在觸發器中進行變量賦值的語句。包含向用戶返回結果的 SELECT 語句或進行變量賦值的語句的觸發器需要特殊處理;這些返回的結果必須寫入允許修改觸發器表的每個應用程序中。如果必須在觸發器中進行變量賦值,則應該在觸發器的開頭使用 SET NOCOUNT 語句以避免返回任何結果集。

DELETE 觸發器不能捕獲 TRUNCATE TABLE 語句。盡管 TRUNCATE TABLE 語句實際上是沒有 WHERE 子句的 DELETE(它刪除所有行),但它是無日志記錄的,因而不能執行觸發器。因為 TRUNCATE TABLE 語句的權限默認授予表所有者且不可轉讓,所以只有表所有者才需要考慮無意中用 TRUNCATE TABLE 語句規避 DELETE 觸發器的問題。

無論有日志記錄還是無日志記錄,WRITETEXT 語句都不激活觸發器。

觸發器中不允許以下 Transact-SQL 語句:

ALTER DATABASE CREATE DATABASE DISK INIT
DISK RESIZE DROP DATABASE LOAD DATABASE
LOAD LOG RECONFIGURE RESTORE DATABASE
RESTORE LOG    

說明  由于 SQL Server 不支持系統表中的用戶定義觸發器,因此建議不要在系統表中創建用戶定義觸發器。

 

多個觸發器

SQL Server 允許為每個數據修改事件(DELETE、INSERT 或 UPDATE)創建多個觸發器。例如,如果對已有 UPDATE 觸發器的表執行 CREATE TRIGGER FOR UPDATE,則將創建另一個更新觸發器。在早期版本中,在每個表上,每個數據修改事件(INSERT、UPDATE 或 DELETE)只允許有一個觸發器。

說明  如果觸發器名稱不同,則 CREATE TRIGGER(兼容級別為 70)的默認行為是在現有的觸發器中添加其它觸發器。如果觸發器名稱相同,則 SQL Server 返回一條錯誤信息。但是,如果兼容級別等于或小于 65,則使用 CREATE TRIGGER 語句創建的新觸發器將替換同一類型的任何現有觸發器,即使觸發器名稱不同。有關更多信息,請參見 sp_dbcmptlevel。

 

遞歸觸發器

當在 sp_dboption 中啟用 recursive triggers 設置時,SQL Server 還允許觸發器的遞歸調用。

遞歸觸發器允許發生兩種類型的遞歸:

  • 間接遞歸

  • 直接遞歸

使用間接遞歸時,應用程序更新表 T1,從而激發觸發器 TR1,該觸發器更新表 T2。在這種情況下,觸發器 T2 將激發并更新 T1。

使用直接遞歸時,應用程序更新表 T1,從而激發觸發器 TR1,該觸發器更新表 T1。由于表 T1 被更新,觸發器 TR1 再次激發,依此類推。

下例既使用了間接觸發器遞歸,又使用了直接觸發器遞歸。假定在表 T1 中定義了兩個更新觸發器 TR1TR2。觸發器 TR1 遞歸地更新表 T1。UPDATE 語句使 TR1TR2 各執行一次。而 TR1 的執行將觸發 TR1(遞歸)和 TR2 的執行。給定觸發器的 inserteddeleted 表只包含與喚醒調用觸發器的 UPDATE 語句相對應的行。

說明  只有啟用 sp_dboptionrecursive triggers 設置,才會發生上述行為。對于為給定事件定義的多個觸發器,并沒有確定的執行順序。每個觸發器都應是自包含的。

 

禁用 recursive triggers 設置只能禁止直接遞歸。若要也禁用間接遞歸,請使用 sp_configurenested triggers 服務器選項設置為 0。

如果任一觸發器執行了 ROLLBACK TRANSACTION 語句,則無論嵌套級是多少,都不會進一步執行其它觸發器。

嵌套觸發器

觸發器最多可以嵌套 32 層。如果一個觸發器更改了包含另一個觸發器的表,則第二個觸發器將激活,然后該觸發器可以再調用第三個觸發器,依此類推。如果鏈中任意一個觸發器引發了無限循環,則會超出嵌套級限制,從而導致取消觸發器。若要禁用嵌套觸發器,請用 sp_configure nested triggers 選項設置為 0(關閉)。默認配置允許嵌套觸發器。如果嵌套觸發器是關閉的,則也將禁用遞歸觸發器,與 sp_dboptionrecursive triggers 設置無關。

延遲名稱解析

SQL Server 允許 Transact-SQL 存儲過程、觸發器和批處理引用編譯時不存在的表。這種能力稱為延遲名稱解析。但是,如果 Transact-SQL 存儲過程、觸發器或批處理引用在存儲過程或觸發器中定義的表,則只有當兼容級別設置(通過執行 sp_dbcmptlevel 設置)等于 65 時,才會在創建時發出警告。如果使用批處理,則在編譯時發出警告。如果引用的表不存在,將在運行時返回錯誤信息。有關更多信息,請參見延遲名稱解析和編譯

權限

CREATE TRIGGER 權限默認授予定義觸發器的表所有者、sysadmin 固定服務器角色成員以及 db_ownerdb_ddladmin 固定數據庫角色成員,并且不可轉讓。

若要檢索表或視圖中的數據,用戶必須在表或視圖中擁有 SELECT 語句權限。若要更新表或視圖的內容,用戶必須在表或視圖中擁有 INSERT、DELETE 和 UPDATE 語句權限。

如果視圖中存在 INSTEAD OF 觸發器,用戶必須在該視圖中有 INSERT、DELETE 和 UPDATE 特權,以對該視圖發出 INSERT、DELETE 和 UPDATE 語句,而不管實際上是否在視圖上執行了這樣的操作。

示例
A. 使用帶有提醒消息的觸發器

當有人試圖在 titles 表中添加或更改數據時,下例將向客戶端顯示一條消息。

說明  消息 50009 是 sysmessages 中的用戶定義消息。有關創建用戶定義消息的更多信息,請參見 sp_addmessage

 


USE pubs
IF EXISTS (SELECT name FROM sysobjects
      
WHERE name = 'reminder' AND type = 'TR')
   
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERTUPDATE 
AS RAISERROR (500091610)
GO
B. 使用帶有提醒電子郵件的觸發器

titles 表更改時,下例將電子郵件發送給指定的人員 (MaryM)。


USE pubs
IF EXISTS (SELECT name FROM sysobjects
      
WHERE name = 'reminder' AND type = 'TR')
   
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERTUPDATEDELETE 
AS
   
EXEC master..xp_sendmail 'MaryM'
      
'Don''t forget to print a report for the distributors.'
GO
C. 在 employee 和 jobs 表之間使用觸發器業務規則

由于 CHECK 約束只能引用定義了列級或表級約束的列,表間的任何約束(在下例中是指業務規則)都必須定義為觸發器。

下例創建一個觸發器,當插入或更新雇員工作級別 (job_lvls) 時,該觸發器檢查指定雇員的工作級別(由此決定薪水)是否處于為該工作定義的范圍內。若要獲得適當的范圍,必須引用 jobs 表。


USE pubs
IF EXISTS (SELECT name FROM sysobjects
      
WHERE name = 'employee_insupd' AND type = 'TR')
   
DROP TRIGGER employee_insupd
GO
CREATE TRIGGER employee_insupd
ON employee
FOR INSERTUPDATE
AS
/* Get the range of level for this job type from the jobs table. */
DECLARE @min_lvl tinyint,
   
@max_lvl tinyint,
   
@emp_lvl tinyint,
   
@job_id smallint
SELECT @min_lvl = min_lvl, 
   
@max_lvl = max_lvl, 
   
@emp_lvl = i.job_lvl,
   
@job_id = i.job_id
FROM employee e INNER JOIN inserted i ON e.emp_id = i.emp_id 
   
JOIN jobs j ON j.job_id = i.job_id
IF (@job_id = 1and (@emp_lvl <> 10
BEGIN
   
RAISERROR ('Job id 1 expects the default level of 10.'161)
   
ROLLBACK TRANSACTION
END
ELSE
IF NOT (@emp_lvl BETWEEN @min_lvl AND @max_lvl)
BEGIN
   
RAISERROR ('The level for job_id:%d should be between %d and %d.',
      
161@job_id@min_lvl@max_lvl)
   
ROLLBACK TRANSACTION
END
D. 使用延遲名稱解析

下例創建兩個觸發器以說明延遲名稱解析。


USE pubs
IF EXISTS (SELECT name FROM sysobjects
      
WHERE name = 'trig1' AND type = 'TR')
   
DROP TRIGGER trig1
GO
-- Creating a trigger on a nonexistent table.
CREATE TRIGGER trig1
on authors
FOR INSERTUPDATEDELETE
AS 
   
SELECT a.au_lname, a.au_fname, x.info 
   
FROM authors a INNER JOIN does_not_exist x 
      
ON a.au_id = x.au_id
GO
-- Here is the statement to actually see the text of the trigger.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c 
   
ON o.id = c.id
WHERE o.type = 'TR' and o.name = 'trig1'

-- Creating a trigger on an existing table, but with a nonexistent 
--
 column.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
      
WHERE name = 'trig2' AND type = 'TR')
   
DROP TRIGGER trig2
GO
CREATE TRIGGER trig2 
ON authors
FOR INSERTUPDATE
AS 
   
DECLARE @fax varchar(12)
   
SELECT @fax = phone   
   
FROM authors
GO
-- Here is the statement to actually see the text of the trigger.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c 
   
ON o.id = c.id
WHERE o.type = 'TR' and o.name = 'trig2'
E. 使用 COLUMNS_UPDATED

下例創建兩個表:一個 employeeData 表和一個 auditEmployeeData 表。人力資源部的成員可以修改 employeeData 表,該表包含敏感的雇員薪水信息。如果更改了雇員的社會保險號碼 (SSN)、年薪或銀行帳戶,則生成審核記錄并插入到 auditEmployeeData 審核表。

通過使用 COLUMNS_UPDATED() 功能,可以快速測試對這些包含敏感雇員信息的列所做的更改。只有在試圖檢測對表中的前 8 列所做的更改時,COLUMNS_UPDATED() 才起作用。

USE pubs
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
   
WHERE TABLE_NAME = 'employeeData')
   
DROP TABLE employeeData
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
   
WHERE TABLE_NAME = 'auditEmployeeData')
   
DROP TABLE auditEmployeeData
GO
CREATE TABLE employeeData (
   emp_id 
int NOT NULL,
   emp_bankAccountNumber 
char (10NOT NULL,
   emp_salary 
int NOT NULL,
   emp_SSN 
char (11NOT NULL,
   emp_lname 
nchar (32NOT NULL,
   emp_fname 
nchar (32NOT NULL,
   emp_manager 
int NOT NULL
   )
GO
CREATE TABLE auditEmployeeData (
   audit_log_id 
uniqueidentifier DEFAULT NEWID(),
   audit_log_type 
char (3NOT NULL,
   audit_emp_id 
int NOT NULL,
   audit_emp_bankAccountNumber 
char (10NULL,
   audit_emp_salary 
int NULL,
   audit_emp_SSN 
char (11NULL,
   audit_user sysname 
DEFAULT SUSER_SNAME(),
   audit_changed 
datetime DEFAULT GETDATE()
   )
GO
CREATE TRIGGER updEmployeeData 
ON employeeData 
FOR update AS
/*Check whether columns 2, 3 or 4 has been updated. If any or all of columns 2, 3 or 4 have been changed, create an audit record. The bitmask is: power(2,(2-1))+power(2,(3-1))+power(2,(4-1)) = 14. To check if all columns 2, 3, and 4 are updated, use = 14 in place of >0 (below).*/

   
IF (COLUMNS_UPDATED() & 14> 0
/*Use IF (COLUMNS_UPDATED() & 14) = 14 to see if all of columns 2, 3, and 4 are updated.*/
      
BEGIN
-- Audit OLD record.
      INSERT INTO auditEmployeeData
         (audit_log_type,
         audit_emp_id,
         audit_emp_bankAccountNumber,
         audit_emp_salary,
         audit_emp_SSN)
         
SELECT 'OLD'
            del.emp_id,
            del.emp_bankAccountNumber,
            del.emp_salary,
            del.emp_SSN
         
FROM deleted del

-- Audit NEW record.
      INSERT INTO auditEmployeeData
         (audit_log_type,
         audit_emp_id,
         audit_emp_bankAccountNumber,
         audit_emp_salary,
         audit_emp_SSN)
         
SELECT 'NEW',
            ins.emp_id,
            ins.emp_bankAccountNumber,
            ins.emp_salary,
            ins.emp_SSN
         
FROM inserted ins
   
END
GO

/*Inserting a new employee does not cause the UPDATE trigger to fire.*/
INSERT INTO employeeData
   
VALUES ( 101'USA-987-01'23000'R-M53550M', N'Mendel', N'Roland'32)
GO

/*Updating the employee record for employee number 101 to change the salary to 51000 causes the UPDATE trigger to fire and an audit trail to be produced.*/

UPDATE employeeData
   
SET emp_salary = 51000
   
WHERE emp_id = 101
GO
SELECT * FROM auditEmployeeData
GO

/*Updating the employee record for employee number 101 to change both the bank account number and social security number (SSN) causes the UPDATE trigger to fire and an audit trail to be produced.*/

UPDATE employeeData
   
SET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'
   
WHERE emp_id = 101
GO
SELECT * FROM auditEmployeeData
GO
F. 使用 COLUMNS_UPDATED 測試 8 列以上

如果必須測試影響到表中前 8 列以外的列的更新時,必須使用 UBSTRING 函數測試由 COLUMNS_UPDATED 返回的適當的位。下例測試影響 Northwind.dbo.Customers 表中的第 3、第 5 或第 9 列的更新。


USE Northwind
DROP TRIGGER  tr1
GO
CREATE TRIGGER tr1 ON Customers
FOR UPDATE AS
   
IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1)=power(2,(3-1))
      
+ power(2,(5-1))) 
      
AND (SUBSTRING(COLUMNS_UPDATED(),2,1)=power(2,(1-1)))
      ) 
   
PRINT 'Columns 3, 5 and 9 updated'
GO

UPDATE Customers 
   
SET ContactName=ContactName,
      Address
=Address,
      Country
=Country
GO

posted on 2008-07-21 15:38 isabc 閱讀(4646) 評論(0)  編輯 收藏 引用 所屬分類: 數據庫

廣告信息(免費廣告聯系)

中文版MSDN:
歡迎體驗

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久国产66| 亚洲欧洲日产国产网站| 亚洲午夜羞羞片| 欧美日韩激情小视频| 亚洲先锋成人| 午夜精品久久久| 伊人久久综合97精品| 亚洲国产精品ⅴa在线观看 | 最新日韩欧美| 欧美日韩免费在线| 性伦欧美刺激片在线观看| 欧美一级一区| 亚洲欧洲综合另类在线| 日韩一级免费观看| 国产亚洲午夜| av成人免费在线| 亚洲国产91| 欧美三级电影大全| 久久久国产精品亚洲一区| 免费观看在线综合色| 亚洲视频日本| 久久久人成影片一区二区三区| 亚洲第一综合天堂另类专| 一本色道久久88精品综合| 国产亚洲精品美女| 亚洲经典一区| 国产亚洲精品一区二区| 亚洲国产精品va在看黑人| 国产精品美女久久| 亚洲观看高清完整版在线观看| 国产精品视频免费一区| 亚洲国产合集| 国产一区二区三区高清在线观看| 亚洲国产小视频| 国产综合在线看| 亚洲天堂av高清| 日韩午夜在线电影| 久久精品人人做人人综合| 亚洲女同同性videoxma| 欧美va亚洲va国产综合| 久久福利影视| 国产精品v欧美精品v日本精品动漫 | 国产日韩欧美一区二区三区四区| 亚洲第一精品影视| 尤物yw午夜国产精品视频明星 | 欧美一区亚洲一区| 欧美日韩高清区| 欧美激情视频一区二区三区免费| 国产欧美日韩另类视频免费观看| 亚洲欧洲精品一区二区三区 | 欧美色精品天天在线观看视频| 免费观看久久久4p| 国产综合18久久久久久| 亚洲夜晚福利在线观看| 中文欧美在线视频| 欧美日韩少妇| 亚洲精选一区| 日韩天堂在线观看| 欧美精品在线网站| 亚洲欧洲精品一区二区三区不卡| 在线国产精品一区| 麻豆久久精品| 亚洲福利在线看| 1000部国产精品成人观看| 久久精品99国产精品日本| 久久这里只有精品视频首页| 国产欧美一区二区三区久久人妖| 亚洲一区二区三区免费在线观看 | 国产精品婷婷| 午夜亚洲精品| 欧美sm极限捆绑bd| 亚洲高清不卡在线| 欧美精品免费在线| 99国产精品自拍| 亚洲欧美日韩在线高清直播| 免费一级欧美在线大片| 欧美精品粉嫩高潮一区二区| 欧美多人爱爱视频网站| 亚洲国产精品久久久久婷婷老年| 久久久精品性| 91久久久久久| 亚洲欧美综合v| 国产亚洲a∨片在线观看| 久久精品亚洲精品国产欧美kt∨| 免播放器亚洲| 最新亚洲激情| 国产精品成人一区二区艾草| 性欧美videos另类喷潮| 久久久91精品国产一区二区精品| 一区三区视频| 欧美精品v国产精品v日韩精品| 亚洲香蕉成视频在线观看| 久久综合九色99| 亚洲精品一区二区三区樱花| 国产精品进线69影院| 久久久久久9999| 亚洲免费观看高清完整版在线观看熊 | 好吊成人免视频| 欧美高清视频一区二区| 一本一道久久综合狠狠老精东影业| 性色av一区二区三区在线观看| 狠狠色丁香久久婷婷综合_中| 欧美日韩高清在线播放| 性久久久久久| 99v久久综合狠狠综合久久| 久久久免费精品| 亚洲砖区区免费| 亚洲精品美女免费| 国产一区亚洲一区| 国产精品国产三级国产aⅴ入口| 久久久美女艺术照精彩视频福利播放 | 欧美一区国产在线| 日韩视频免费观看高清完整版| 国产日韩精品入口| 欧美日韩综合在线| 欧美大片网址| 久久久激情视频| 欧美一级播放| 亚洲香蕉成视频在线观看| 最新日韩在线| 欧美高清不卡| 久久字幕精品一区| 久久精品亚洲精品| 亚洲免费在线播放| 日韩亚洲欧美中文三级| 精品成人在线| 国内精品久久久久久久97牛牛| 国产精品欧美日韩| 欧美日韩亚洲一区三区 | 亚洲免费视频网站| 99国内精品久久| 亚洲经典一区| 亚洲国产天堂久久国产91| 猛男gaygay欧美视频| 欧美亚洲日本网站| 亚洲在线第一页| 亚洲综合国产| 亚洲伊人观看| 亚洲你懂的在线视频| 亚洲一区影音先锋| 一区二区三区成人精品| 日韩视频一区二区三区| 欧美激情一区二区三区| 欧美国产日韩一区二区在线观看 | 久久久噜噜噜久久狠狠50岁| 欧美一区二区在线看| 午夜视频久久久| 午夜一级久久| 久久国产精品一区二区三区四区| 欧美在线免费播放| 久久一区二区精品| 欧美成黄导航| 亚洲国产精品久久久久秋霞不卡| 欧美韩国日本一区| 亚洲伦理在线免费看| 一区二区三区日韩精品视频| 亚洲最新视频在线播放| 亚洲色图自拍| 欧美在线视频播放| 老司机久久99久久精品播放免费| 麻豆久久久9性大片| 欧美啪啪一区| 国产三级欧美三级日产三级99| 影音先锋另类| 99re6热在线精品视频播放速度| 一区二区欧美在线观看| 欧美中文在线观看| 欧美阿v一级看视频| 亚洲精品国产品国语在线app | 欧美黄色日本| 亚洲夜间福利| 麻豆成人在线观看| 国产精品乱子久久久久| 极品中文字幕一区| 99在线热播精品免费99热| 欧美一站二站| 亚洲激情一区二区| 亚洲欧美国产视频| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲午夜久久久久久久久电影院 | 亚洲小少妇裸体bbw| 久色婷婷小香蕉久久| 国产精品久久久久9999吃药| 国产一区二区三区黄视频| 日韩午夜激情| 毛片精品免费在线观看| 一区二区三区国产在线| 久久久久久久久久码影片| 国产精品jizz在线观看美国| 亚洲大片一区二区三区| 午夜伦理片一区| 亚洲国产精选| 久久五月婷婷丁香社区| 欧美亚洲成人精品| 亚洲欧洲日本在线| 久久久久看片| 亚洲欧美另类中文字幕| 国产精品国产三级国产专区53 | 亚洲欧美日韩国产成人| 亚洲国产片色|