在軟體實施程序中,也許會有這樣的問題: 表中資料出現非預期的結果,此時不確定是程式問題,哪個程式,存盤程序,觸發器.. 或還是人為修改的結果,此時可以用觸發器對特定的表欄位做跟蹤監視,記錄每次新增,修改,洗掉此欄位值的操作詳細資訊(含登錄名,主機名,IP地址,執行的TSQL陳述句,程式名等等), 以利于問題的排查.
-- 建測驗表
CREATE TABLE sto
(
id INT NOT NULL, -- 主鍵欄位
de DATETIME -- 被跟蹤的欄位
CONSTRAINT pk_sto
PRIMARY KEY (id)
);
-- 建日志表
CREATE TABLE log_sto
(
logid INT NOT NULL IDENTITY(1, 1), -- 日志序號(日志主鍵)
operate VARCHAR(10), -- 操作型別 如Insert,Update,Delete.
id INT, -- 原表ID(主鍵)
old_de DATETIME, -- de欄位舊值
new_de DATETIME, -- de欄位新值
spid INT NOT NULL, -- spid
login_name VARCHAR(100), -- 登錄名
prog_name VARCHAR(100), -- 程式名
hostname VARCHAR(100), -- 主機名
ipaddress VARCHAR(100), -- IP地址
runsql VARCHAR(4000), -- 執行的TSQL代碼
UDate DATETIME -- 操作日期時間
CONSTRAINT pk_logsto
PRIMARY KEY (logid)
);
GO
-- 建跟蹤觸發器
CREATE TRIGGER tr_sto
ON sto
AFTER UPDATE, INSERT, DELETE
AS
BEGIN
DECLARE @di TABLE
(
et VARCHAR(200),
pt VARCHAR(200),
ei VARCHAR(MAX)
);
INSERT INTO @di
EXEC ('dbcc inputbuffer(@@spid)');
DECLARE @op VARCHAR(10);
SELECT
@op = CASE WHEN EXISTS ( SELECT 1 FROM inserted ) AND EXISTS (SELECT 1 FROM deleted)
THEN 'Update'
WHEN EXISTS ( SELECT 1 FROM inserted ) AND NOT EXISTS (SELECT 1 FROM deleted)
THEN 'Insert'
WHEN NOT EXISTS(SELECT 1 FROM inserted ) AND EXISTS (SELECT 1 FROM deleted)
THEN 'Delete'
END;
IF @op IN (
'Update', 'Insert'
)
BEGIN
INSERT INTO log_sto
(
operate,
id,
old_de,
new_de,
spid,
login_name,
prog_name,
hostname,
ipaddress,
runsql,
UDate
)
SELECT
@op,
n.id,
o.de,
n.de,
@@spid,
(
SELECT
login_name
FROM
sys.dm_exec_sessions
WHERE
session_id = @@spid
),
(
SELECT
program_name
FROM
sys.dm_exec_sessions
WHERE
session_id = @@spid
),
(
SELECT
hostname
FROM
sys.sysprocesses
WHERE
spid = @@spid
),
(
SELECT
client_net_address
FROM
sys.dm_exec_connections
WHERE
session_id = @@spid
),
(
SELECT TOP 1
ISNULL(ei, '')
FROM
@di
),
GETDATE()
FROM
inserted n
LEFT JOIN
deleted o
ON o.id = n.id;
END;
ELSE
BEGIN
INSERT INTO log_sto
(
operate,
id,
old_de,
new_de,
spid,
login_name,
prog_name,
hostname,
ipaddress,
runsql,
UDate
)
SELECT
@op,
o.id,
o.de,
NULL,
@@spid,
(
SELECT
login_name
FROM
sys.dm_exec_sessions
WHERE
session_id = @@spid
),
(
SELECT
program_name
FROM
sys.dm_exec_sessions
WHERE
session_id = @@spid
),
(
SELECT
hostname
FROM
sys.sysprocesses
WHERE
spid = @@spid
),
(
SELECT
client_net_address
FROM
sys.dm_exec_connections
WHERE
session_id = @@spid
),
(
SELECT TOP 1
ISNULL(ei, '')
FROM
@di
),
GETDATE()
FROM
deleted o;
END;
END;
GO
--> 測驗DML操作
-- 操作1
INSERT INTO sto
(
id,
de
)
VALUES
(
1, '2012-01-01 05:06:07'
);
GO
-- 操作2
INSERT INTO sto
(
id,
de
)
VALUES
(
2, '2012-01-01 06:06:07'
);
GO
-- 操作3
UPDATE
sto
SET
de = getdate()
WHERE
id = 2;
GO
-- 操作4
UPDATE
sto
SET
de = getdate()
WHERE
id = 1;
GO
-- 操作5
INSERT INTO sto
(
id,
de
)
VALUES
(
5, '2012-01-01 15:26:37'
);
GO
-- 操作6
DELETE sto
WHERE
id = 2;
GO
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/34276.html
標籤:SQL Server
上一篇:觸發器TRIGGER 自增IDENTITY 聚集索引CLUSTERED
下一篇:sql比較字串,比的到底是什么?
