触发器怎么执行
/**//*
建立虛擬測試環境,包含:表[卷煙庫存表],表[卷煙銷售表]。
請大家注意跟蹤這兩個表的數據,體會觸發器到底執行了什么業務邏輯,對數據有什么影響。
為了能更清晰的表述觸發器的作用,表結構存在數據冗余,且不符合第三范式,這里特此說明。
*/?
USE?test
GO
IF?EXISTS?(SELECT?NAME?FROM?SYSOBJECTS?WHERE?XTYPE?=?'U'?AND?NAME?=?'卷煙庫存表')
DROP?TABLE?卷煙庫存表
GO
IF?EXISTS?(SELECT?NAME?FROM?SYSOBJECTS?WHERE?XTYPE?=?'U'?AND?NAME?=?'卷煙銷售表')
DROP?TABLE?卷煙銷售表
GO
--業務規則:銷售金額?=?銷售數量?*?銷售單價?業務規則。
CREATE?TABLE?卷煙銷售表
(
卷煙品牌?VARCHAR(40)?PRIMARY?KEY?NOT?NULL,
購貨商?VARCHAR(40)?NULL,
銷售數量?INT?NULL,
銷售單價?MONEY?NULL,
銷售金額?MONEY?NULL
)
GO
--業務規則:庫存金額?=?庫存數量?*?庫存單價?業務規則。
CREATE?TABLE?卷煙庫存表
(
卷煙品牌?VARCHAR(40)?PRIMARY?KEY?NOT?NULL,
庫存數量?INT?NULL,
庫存單價?MONEY?NULL,
庫存金額?MONEY?NULL
)
GO
--創建觸發器,示例1
/**//*
創建觸發器[T_INSERT_卷煙庫存表],這個觸發器較簡單。
說明:?每當[卷煙庫存表]發生?INSERT?動作,則引發該觸發器。
觸發器功能:?強制執行業務規則,保證插入的數據中,庫存金額?=?庫存數量?*?庫存單價。
注意:?[INSERTED]、[DELETED]為系統表,不可創建、修改、刪除,但可以調用。
重要:?這兩個系統表的結構同插入數據的表的結構。
*/
IF?EXISTS?(SELECT?NAME?FROM?SYSOBJECTS?WHERE?XTYPE?=?'TR'?AND?NAME?=?'T_INSERT_卷煙庫存表')
DROP?TRIGGER?T_INSERT_卷煙庫存表
GO
CREATE?TRIGGER?T_INSERT_卷煙庫存表
ON?卷煙庫存表
FOR?INSERT
AS
--提交事務處理
BEGIN?TRANSACTION
--強制執行下列語句,保證業務規則
UPDATE?卷煙庫存表
SET?庫存金額?=?庫存數量?*?庫存單價
WHERE?卷煙品牌?IN?(SELECT?卷煙品牌?from?INSERTED)
COMMIT?TRANSACTION
GO
/**//*?
針對[卷煙庫存表],插入測試數據:
注意,第一條數據(紅塔山新勢力)中的數據符合業務規則,
第二條數據(紅塔山人為峰)中,[庫存金額]空,不符合業務規則,
第三條數據(云南映像)中,[庫存金額]不等于[庫存數量]乘以[庫存單價],不符合業務規則。
第四條數據庫存數量為0。
請注意在插入數據后,檢查[卷煙庫存表]中的數據是否?庫存金額?=?庫存數量?*?庫存單價。
*/
INSERT?INTO?卷煙庫存表(卷煙品牌,庫存數量,庫存單價,庫存金額)
SELECT?'紅塔山新勢力',100,12,1200?UNION?ALL
SELECT?'紅塔山人為峰',100,22,NULL?UNION?ALL
SELECT?'云南映像',100,60,500?UNION?ALL
SELECT?'玉溪',0,30,0
GO
--查詢數據
SELECT?*?FROM?卷煙庫存表
GO
/**//*
結果集
RecordId?卷煙品牌?庫存數量?庫存單價?庫存金額
--------?------------?--------?-------?---------
1?紅塔山新勢力?100?12.0000?1200.0000
2?紅塔山人為峰?100?22.0000?2200.0000
3?云南映像?100?60.0000?6000.0000
4?玉溪?0?30.0000?.0000
(所影響的行數為?4?行)
*/
--觸發器示例2
/**//*
創建觸發器[T_INSERT_卷煙銷售表],該觸發器較復雜。
說明:?每當[卷煙庫存表]發生?INSERT?動作,則引發該觸發器。
觸發器功能:?實現業務規則。
業務規則:?如果銷售的卷煙品牌不存在庫存或者庫存為零,則返回錯誤。
否則則自動減少[卷煙庫存表]中對應品牌卷煙的庫存數量和庫存金額。
*/
IF?EXISTS?(SELECT?NAME?FROM?SYSOBJECTS?WHERE?XTYPE?=?'TR'?AND?NAME?=?'T_INSERT_卷煙銷售表')
DROP?TRIGGER?T_INSERT_卷煙銷售表
GO
CREATE?TRIGGER?T_INSERT_卷煙銷售表
ON?卷煙銷售表
FOR?INSERT
AS
BEGIN?TRANSACTION
--檢查數據的合法性:銷售的卷煙是否有庫存,或者庫存是否大于零
IF?NOT?EXISTS?(
SELECT?庫存數量
FROM?卷煙庫存表
WHERE?卷煙品牌?IN?(SELECT?卷煙品牌?FROM?INSERTED)
)
BEGIN
--返回錯誤提示
RAISERROR('錯誤!該卷煙不存在庫存,不能銷售。',16,1)
--回滾事務
ROLLBACK
RETURN
END
IF?EXISTS?(
SELECT?庫存數量
FROM?卷煙庫存表
WHERE?卷煙品牌?IN?(SELECT?卷煙品牌?FROM?INSERTED)?AND
庫存數量?<=?0?
)
BEGIN
--返回錯誤提示
RAISERROR('錯誤!該卷煙庫存小于等于0,不能銷售。',16,1)
--回滾事務
ROLLBACK
RETURN
END
--對合法的數據進行處理
--強制執行下列語句,保證業務規則
UPDATE?卷煙銷售表
SET?銷售金額?=?銷售數量?*?銷售單價
WHERE?卷煙品牌?IN?(SELECT?卷煙品牌?FROM?INSERTED)
DECLARE?@卷煙品牌?VARCHAR(40)
SET?@卷煙品牌?=?(SELECT?卷煙品牌?FROM?INSERTED)
DECLARE?@銷售數量?MONEY
SET?@銷售數量?=?(SELECT?銷售數量?FROM?INSERTED)
UPDATE?卷煙庫存表
SET?庫存數量?=?庫存數量?-?@銷售數量,
庫存金額?=?(庫存數量?-?@銷售數量)*庫存單價
WHERE?卷煙品牌?=?@卷煙品牌
COMMIT?TRANSACTION
GO
--請大家自行跟蹤[卷煙庫存表]和[卷煙銷售表]的數據變化。
--針對[卷煙銷售表],插入第一條測試數據,該數據是正常的。
INSERT?INTO?卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額)
SELECT?'紅塔山新勢力','某購貨商',10,12,1200
GO
--針對[卷煙銷售表],插入第二條測試數據,該數據?銷售金額?不等于?銷售單價?*?銷售數量。
--觸發器將自動更正數據,使?銷售金額?等于?銷售單價?*?銷售數量。
INSERT?INTO?卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額)
SELECT?'紅塔山人為峰','某購貨商',10,22,2000
GO
--針對[卷煙銷售表],插入第三條測試數據,該數據中的卷煙品牌在?卷煙庫存表中找不到對應。
--觸發器將報錯。
INSERT?INTO?卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額)
SELECT?'紅河V8','某購貨商',10,60,600
GO
/**//*
結果集
服務器:?消息?50000,級別?16,狀態?1,過程?T_INSERT_卷煙銷售表,行?15
錯誤!該卷煙不存在庫存,不能銷售。
*/
--針對[卷煙銷售表],插入第三條測試數據,該數據中的卷煙品牌在?卷煙庫存表中庫存為0。
--觸發器將報錯。
INSERT?INTO?卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額)
SELECT?'玉溪','某購貨商',10,30,300
GO
/**//*
結果集
服務器:?消息?50000,級別?16,狀態?1,過程?T_INSERT_卷煙銷售表,行?29
錯誤!該卷煙庫存小于等于0,不能銷售。
*/
--查詢數據
SELECT?*?FROM?卷煙庫存表
SELECT?*?FROM?卷煙銷售表
GO
/**//*
補充:
1、本示例主要通過一個簡單的業務規則實現來進行觸發器使用的說明,具體的要根據需要靈活處理;
2、關于觸發器要理解并運用好?INSERTED?,DELETED?兩個系統表;
3、本示例創建的觸發器都是?FOR?INSERT?,具體的語法可參考:
Trigger語法
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?)?]
[?n?]
|?IF?(?COLUMNS_UPDATED?(?)?{?bitwise_operator?}?updated_bitmask?)
{?comparison_operator?}?column_bitmask?[?n?]
}?]?
sql_statement?[?n?]?
}?
}?
4、關于觸發器,還應該注意
(1)、DELETE?觸發器不能捕獲?TRUNCATE?TABLE?語句。
(2)、觸發器中不允許以下?Transact-SQL?語句:
ALTER?DATABASE?CREATE?DATABASE?DISK?INIT?
DISK?RESIZE?DROP?DATABASE?LOAD?DATABASE?
LOAD?LOG?RECONFIGURE?RESTORE?DATABASE?
RESTORE?LOG?
(3)、觸發器最多可以嵌套?32?層。
*/
--修改觸發器
--實質上,是將?CREATE?TRIGGER??修改為?ALTER?TRIGGER?即可。
--刪除觸發器
DROP?TRIGGER?xxx
GO
--刪除測試環境
DROP?TABLE?卷煙庫存表
GO
DROP?TABLE?卷煙銷售表
GO
DROP?TRIGGER?T_INSERT_卷煙庫存表
GO
DROP?TRIGGER?T_INSERT_卷煙銷售表
GO
/**//**----------------------------------------------------------------------
##################################################################
觸發器的基礎知識和例子
:create?trigger?tr_name
on?table/view
{for?|?after?|?instead?of?}?[update][,][insert][,][delete]
[with?encryption]
as?{batch?|?if?update?(col_name)?[{and|or}?update?(col_name)]?}
說明:
1?tr_name?:觸發器名稱
2?on?table/view?:觸發器所作用的表。一個觸發器只能作用于一個表
3?for?和after?:同義
4?after?與instead?of?:sql?2000新增項目afrer?與?instead?of?的區別
After?
在觸發事件發生以后才被激活,只可以建立在表上?
Instead?of
代替了相應的觸發事件而被執行,既可以建立在表上也可以建立在視圖上
5?insert、update、delete:激活觸發器的三種操作,可以同時執行,也可選其一
6?if?update?(col_name):表明所作的操作對指定列是否有影響,有影響,則激活觸發器。此外,因為delete?操作只對行有影響,
所以如果使用delete操作就不能用這條語句了(雖然使用也不出錯,但是不能激活觸發器,沒意義)。
7?觸發器執行時用到的兩個特殊表:deleted?,inserted
deleted?和inserted?可以說是一種特殊的臨時表,是在進行激活觸發器時由系統自動生成的,其結構與觸發器作用的表結構是一
樣的,只是存放?的數據有差異。
續
下面表格說明deleted?與inserted?數據的差異
deleted?與inserted?數據的差異
Inserted?
存放進行insert和update?操作后的數據?
Deleted
存放進行delete?和update操作前的數據
注意:update?操作相當于先進行delete?再進行insert?,所以在進行update操作時,修改前的數據拷貝一條到deleted?表中,修改后
的數據在存到觸發器作用的表的同時,也同時生成一條拷貝到insered表中?
---------------------------------------------------------------------------*/
建立虛擬測試環境,包含:表[卷煙庫存表],表[卷煙銷售表]。
請大家注意跟蹤這兩個表的數據,體會觸發器到底執行了什么業務邏輯,對數據有什么影響。
為了能更清晰的表述觸發器的作用,表結構存在數據冗余,且不符合第三范式,這里特此說明。
*/?
USE?test
GO
IF?EXISTS?(SELECT?NAME?FROM?SYSOBJECTS?WHERE?XTYPE?=?'U'?AND?NAME?=?'卷煙庫存表')
DROP?TABLE?卷煙庫存表
GO
IF?EXISTS?(SELECT?NAME?FROM?SYSOBJECTS?WHERE?XTYPE?=?'U'?AND?NAME?=?'卷煙銷售表')
DROP?TABLE?卷煙銷售表
GO
--業務規則:銷售金額?=?銷售數量?*?銷售單價?業務規則。
CREATE?TABLE?卷煙銷售表
(
卷煙品牌?VARCHAR(40)?PRIMARY?KEY?NOT?NULL,
購貨商?VARCHAR(40)?NULL,
銷售數量?INT?NULL,
銷售單價?MONEY?NULL,
銷售金額?MONEY?NULL
)
GO
--業務規則:庫存金額?=?庫存數量?*?庫存單價?業務規則。
CREATE?TABLE?卷煙庫存表
(
卷煙品牌?VARCHAR(40)?PRIMARY?KEY?NOT?NULL,
庫存數量?INT?NULL,
庫存單價?MONEY?NULL,
庫存金額?MONEY?NULL
)
GO
--創建觸發器,示例1
/**//*
創建觸發器[T_INSERT_卷煙庫存表],這個觸發器較簡單。
說明:?每當[卷煙庫存表]發生?INSERT?動作,則引發該觸發器。
觸發器功能:?強制執行業務規則,保證插入的數據中,庫存金額?=?庫存數量?*?庫存單價。
注意:?[INSERTED]、[DELETED]為系統表,不可創建、修改、刪除,但可以調用。
重要:?這兩個系統表的結構同插入數據的表的結構。
*/
IF?EXISTS?(SELECT?NAME?FROM?SYSOBJECTS?WHERE?XTYPE?=?'TR'?AND?NAME?=?'T_INSERT_卷煙庫存表')
DROP?TRIGGER?T_INSERT_卷煙庫存表
GO
CREATE?TRIGGER?T_INSERT_卷煙庫存表
ON?卷煙庫存表
FOR?INSERT
AS
--提交事務處理
BEGIN?TRANSACTION
--強制執行下列語句,保證業務規則
UPDATE?卷煙庫存表
SET?庫存金額?=?庫存數量?*?庫存單價
WHERE?卷煙品牌?IN?(SELECT?卷煙品牌?from?INSERTED)
COMMIT?TRANSACTION
GO
/**//*?
針對[卷煙庫存表],插入測試數據:
注意,第一條數據(紅塔山新勢力)中的數據符合業務規則,
第二條數據(紅塔山人為峰)中,[庫存金額]空,不符合業務規則,
第三條數據(云南映像)中,[庫存金額]不等于[庫存數量]乘以[庫存單價],不符合業務規則。
第四條數據庫存數量為0。
請注意在插入數據后,檢查[卷煙庫存表]中的數據是否?庫存金額?=?庫存數量?*?庫存單價。
*/
INSERT?INTO?卷煙庫存表(卷煙品牌,庫存數量,庫存單價,庫存金額)
SELECT?'紅塔山新勢力',100,12,1200?UNION?ALL
SELECT?'紅塔山人為峰',100,22,NULL?UNION?ALL
SELECT?'云南映像',100,60,500?UNION?ALL
SELECT?'玉溪',0,30,0
GO
--查詢數據
SELECT?*?FROM?卷煙庫存表
GO
/**//*
結果集
RecordId?卷煙品牌?庫存數量?庫存單價?庫存金額
--------?------------?--------?-------?---------
1?紅塔山新勢力?100?12.0000?1200.0000
2?紅塔山人為峰?100?22.0000?2200.0000
3?云南映像?100?60.0000?6000.0000
4?玉溪?0?30.0000?.0000
(所影響的行數為?4?行)
*/
--觸發器示例2
/**//*
創建觸發器[T_INSERT_卷煙銷售表],該觸發器較復雜。
說明:?每當[卷煙庫存表]發生?INSERT?動作,則引發該觸發器。
觸發器功能:?實現業務規則。
業務規則:?如果銷售的卷煙品牌不存在庫存或者庫存為零,則返回錯誤。
否則則自動減少[卷煙庫存表]中對應品牌卷煙的庫存數量和庫存金額。
*/
IF?EXISTS?(SELECT?NAME?FROM?SYSOBJECTS?WHERE?XTYPE?=?'TR'?AND?NAME?=?'T_INSERT_卷煙銷售表')
DROP?TRIGGER?T_INSERT_卷煙銷售表
GO
CREATE?TRIGGER?T_INSERT_卷煙銷售表
ON?卷煙銷售表
FOR?INSERT
AS
BEGIN?TRANSACTION
--檢查數據的合法性:銷售的卷煙是否有庫存,或者庫存是否大于零
IF?NOT?EXISTS?(
SELECT?庫存數量
FROM?卷煙庫存表
WHERE?卷煙品牌?IN?(SELECT?卷煙品牌?FROM?INSERTED)
)
BEGIN
--返回錯誤提示
RAISERROR('錯誤!該卷煙不存在庫存,不能銷售。',16,1)
--回滾事務
ROLLBACK
RETURN
END
IF?EXISTS?(
SELECT?庫存數量
FROM?卷煙庫存表
WHERE?卷煙品牌?IN?(SELECT?卷煙品牌?FROM?INSERTED)?AND
庫存數量?<=?0?
)
BEGIN
--返回錯誤提示
RAISERROR('錯誤!該卷煙庫存小于等于0,不能銷售。',16,1)
--回滾事務
ROLLBACK
RETURN
END
--對合法的數據進行處理
--強制執行下列語句,保證業務規則
UPDATE?卷煙銷售表
SET?銷售金額?=?銷售數量?*?銷售單價
WHERE?卷煙品牌?IN?(SELECT?卷煙品牌?FROM?INSERTED)
DECLARE?@卷煙品牌?VARCHAR(40)
SET?@卷煙品牌?=?(SELECT?卷煙品牌?FROM?INSERTED)
DECLARE?@銷售數量?MONEY
SET?@銷售數量?=?(SELECT?銷售數量?FROM?INSERTED)
UPDATE?卷煙庫存表
SET?庫存數量?=?庫存數量?-?@銷售數量,
庫存金額?=?(庫存數量?-?@銷售數量)*庫存單價
WHERE?卷煙品牌?=?@卷煙品牌
COMMIT?TRANSACTION
GO
--請大家自行跟蹤[卷煙庫存表]和[卷煙銷售表]的數據變化。
--針對[卷煙銷售表],插入第一條測試數據,該數據是正常的。
INSERT?INTO?卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額)
SELECT?'紅塔山新勢力','某購貨商',10,12,1200
GO
--針對[卷煙銷售表],插入第二條測試數據,該數據?銷售金額?不等于?銷售單價?*?銷售數量。
--觸發器將自動更正數據,使?銷售金額?等于?銷售單價?*?銷售數量。
INSERT?INTO?卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額)
SELECT?'紅塔山人為峰','某購貨商',10,22,2000
GO
--針對[卷煙銷售表],插入第三條測試數據,該數據中的卷煙品牌在?卷煙庫存表中找不到對應。
--觸發器將報錯。
INSERT?INTO?卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額)
SELECT?'紅河V8','某購貨商',10,60,600
GO
/**//*
結果集
服務器:?消息?50000,級別?16,狀態?1,過程?T_INSERT_卷煙銷售表,行?15
錯誤!該卷煙不存在庫存,不能銷售。
*/
--針對[卷煙銷售表],插入第三條測試數據,該數據中的卷煙品牌在?卷煙庫存表中庫存為0。
--觸發器將報錯。
INSERT?INTO?卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額)
SELECT?'玉溪','某購貨商',10,30,300
GO
/**//*
結果集
服務器:?消息?50000,級別?16,狀態?1,過程?T_INSERT_卷煙銷售表,行?29
錯誤!該卷煙庫存小于等于0,不能銷售。
*/
--查詢數據
SELECT?*?FROM?卷煙庫存表
SELECT?*?FROM?卷煙銷售表
GO
/**//*
補充:
1、本示例主要通過一個簡單的業務規則實現來進行觸發器使用的說明,具體的要根據需要靈活處理;
2、關于觸發器要理解并運用好?INSERTED?,DELETED?兩個系統表;
3、本示例創建的觸發器都是?FOR?INSERT?,具體的語法可參考:
Trigger語法
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?)?]
[?n?]
|?IF?(?COLUMNS_UPDATED?(?)?{?bitwise_operator?}?updated_bitmask?)
{?comparison_operator?}?column_bitmask?[?n?]
}?]?
sql_statement?[?n?]?
}?
}?
4、關于觸發器,還應該注意
(1)、DELETE?觸發器不能捕獲?TRUNCATE?TABLE?語句。
(2)、觸發器中不允許以下?Transact-SQL?語句:
ALTER?DATABASE?CREATE?DATABASE?DISK?INIT?
DISK?RESIZE?DROP?DATABASE?LOAD?DATABASE?
LOAD?LOG?RECONFIGURE?RESTORE?DATABASE?
RESTORE?LOG?
(3)、觸發器最多可以嵌套?32?層。
*/
--修改觸發器
--實質上,是將?CREATE?TRIGGER??修改為?ALTER?TRIGGER?即可。
--刪除觸發器
DROP?TRIGGER?xxx
GO
--刪除測試環境
DROP?TABLE?卷煙庫存表
GO
DROP?TABLE?卷煙銷售表
GO
DROP?TRIGGER?T_INSERT_卷煙庫存表
GO
DROP?TRIGGER?T_INSERT_卷煙銷售表
GO
/**//**----------------------------------------------------------------------
##################################################################
觸發器的基礎知識和例子
:create?trigger?tr_name
on?table/view
{for?|?after?|?instead?of?}?[update][,][insert][,][delete]
[with?encryption]
as?{batch?|?if?update?(col_name)?[{and|or}?update?(col_name)]?}
說明:
1?tr_name?:觸發器名稱
2?on?table/view?:觸發器所作用的表。一個觸發器只能作用于一個表
3?for?和after?:同義
4?after?與instead?of?:sql?2000新增項目afrer?與?instead?of?的區別
After?
在觸發事件發生以后才被激活,只可以建立在表上?
Instead?of
代替了相應的觸發事件而被執行,既可以建立在表上也可以建立在視圖上
5?insert、update、delete:激活觸發器的三種操作,可以同時執行,也可選其一
6?if?update?(col_name):表明所作的操作對指定列是否有影響,有影響,則激活觸發器。此外,因為delete?操作只對行有影響,
所以如果使用delete操作就不能用這條語句了(雖然使用也不出錯,但是不能激活觸發器,沒意義)。
7?觸發器執行時用到的兩個特殊表:deleted?,inserted
deleted?和inserted?可以說是一種特殊的臨時表,是在進行激活觸發器時由系統自動生成的,其結構與觸發器作用的表結構是一
樣的,只是存放?的數據有差異。
續
下面表格說明deleted?與inserted?數據的差異
deleted?與inserted?數據的差異
Inserted?
存放進行insert和update?操作后的數據?
Deleted
存放進行delete?和update操作前的數據
注意:update?操作相當于先進行delete?再進行insert?,所以在進行update操作時,修改前的數據拷貝一條到deleted?表中,修改后
的數據在存到觸發器作用的表的同時,也同時生成一條拷貝到insered表中?
---------------------------------------------------------------------------*/
轉載于:https://www.cnblogs.com/ssihc/archive/2006/07/31/464258.html
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
- 上一篇: secret sharing;拉格朗日插
- 下一篇: window系统下的堆栈溢出 作者:ip