安装我们的模式和表进行测试
SET NOCOUNT ON
IF OBJECT_ID('TempTable', 'U') IS NOT NULL DROP TABLE TempTable;
IF OBJECT_ID('MasterTable', 'U') IS NOT NULL DROP TABLE MasterTable;
IF OBJECT_ID('ForeignKeyTableCOL1', 'U') IS NOT NULL DROP TABLE ForeignKeyTableCOL1;
IF OBJECT_ID('ForeignKeyTableCOL2', 'U') IS NOT NULL DROP TABLE ForeignKeyTableCOL2;
IF OBJECT_ID('HistoryTable', 'U') IS NOT NULL DROP TABLE HistoryTable;
IF OBJECT_ID('ErrorTable', 'U') IS NOT NULL DROP TABLE ErrorTable;
CREATE TABLE ForeignKeyTableCOL1 (COL1 varchar(10) PRIMARY KEY)
CREATE TABLE ForeignKeyTableCOL2 (COL2 varchar(10) PRIMARY KEY)
CREATE TABLE TempTable (TempTableID int IDENTITY(1,1), PKRecordID int, COL1 varchar(10), COL2 varchar(10), COL3 varchar(10), COL4 varchar(10), COL5 varchar(10), Success char(1))
CREATE TABLE MasterTable (PKRecordID int PRIMARY KEY, COL1 varchar(10), COL2 varchar(10), COL3 varchar(10), COL4 varchar(10), COL5 varchar(10))
ALTER TABLE MasterTable ADD CONSTRAINT FK_MasterTable_ForeignKeyTableCOL1 FOREIGN KEY (COL1) REFERENCES ForeignKeyTableCOL1 (COL1)
ALTER TABLE MasterTable ADD CONSTRAINT FK_MasterTable_ForeignKeyTableCOL2 FOREIGN KEY (COL2) REFERENCES ForeignKeyTableCOL2 (COL2)
CREATE TABLE HistoryTable (HistoryTableID int IDENTITY(1,1) PRIMARY KEY, PKRecordID int, ColumnChanged varchar(50), OldValue varchar(10), NewValue varchar(10))
CREATE TABLE ErrorTable (ErrorTableID int IDENTITY(1,1) PRIMARY KEY, PKRecordID int, TableName varchar(50), TablePK int, ErrorDateTime datetime, ErrorCode int, ErrorMsg nvarchar(4000))
GO
INSERT ForeignKeyTableCOL1 SELECT 'A' UNION SELECT 'B' UNION SELECT 'C'
INSERT ForeignKeyTableCOL2 SELECT 'A' UNION SELECT 'B' UNION SELECT 'C'
INSERT TempTable SELECT 1, 'A', 'A', 'A', 'A', 'A', 'N'
INSERT TempTable SELECT 2, 'B', 'B', 'B', 'B', 'B', 'N'
INSERT TempTable SELECT 3, 'C', 'C', 'C', 'C', 'C', 'N'
INSERT TempTable SELECT 1, 'D', 'A', 'A', 'A', 'A', 'N'
INSERT TempTable SELECT 1, 'A', 'D', 'A', 'A', 'A', 'N'
INSERT TempTable SELECT 1, 'D', 'D', 'A', 'A', 'A', 'N'
INSERT TempTable SELECT 2, 'A', 'B', 'B', 'B', 'B', 'N'
INSERT TempTable SELECT 3, 'A', 'B', 'C', 'C', 'C', 'N'
INSERT TempTable SELECT 4, 'D', 'D', 'D', 'D', 'D', 'N'
SET NOCOUNT OFF
执行INSERTS
和UPDATES
与审计/错误日志
DECLARE @PKRecordID int, @COL1 varchar(10), @COL2 varchar(10), @COL3 varchar(10), @COL4 varchar(10), @COL5 varchar(10), @TempTableID int
DECLARE @PKRecordID_OLD int, @COL1_OLD varchar(10), @COL2_OLD varchar(10), @COL3_OLD varchar(10), @COL4_OLD varchar(10), @COL5_OLD varchar(10)
DECLARE temp_cursor CURSOR FOR
SELECT TempTableID, PKRecordID, COL1, COL2, COL3, COL4, COL5
FROM TempTable
ORDER BY TempTableID;
OPEN temp_cursor
FETCH NEXT FROM temp_cursor
INTO @TempTableID, @PKRecordID, @COL1, @COL2, @COL3, @COL4, @COL5
WHILE @@FETCH_STATUS = 0
BEGIN
--SELECT @idx, @COL1, @COL2, @COL3, @COL4, @COL5
BEGIN TRY
IF EXISTS (SELECT * FROM MasterTable WHERE PKRecordID = @PKRecordID)
BEGIN
SELECT @COL1_OLD = COL1
,@COL2_OLD = COL2
,@COL3_OLD = COL3
,@COL4_OLD = COL4
,@COL5_OLD = COL5
FROM MasterTable
WHERE PKRecordID = @PKRecordID
UPDATE MasterTable
SET COL1 = @COL1
,COL2 = @COL2
,COL3 = @COL3
,COL4 = @COL4
,COL5 = @COL5
WHERE PKRecordID = @PKRecordID
INSERT HistoryTable (PKRecordID, ColumnChanged, OldValue, NewValue)
SELECT @PKRecordID, 'COL1', @COL1_OLD, @COL1
WHERE EXISTS (SELECT @COL1 EXCEPT SELECT @COL1_OLD)
INSERT HistoryTable (PKRecordID, ColumnChanged, OldValue, NewValue)
SELECT @PKRecordID, 'COL2', @COL2_OLD, @COL2
WHERE EXISTS (SELECT @COL2 EXCEPT SELECT @COL2_OLD)
INSERT HistoryTable (PKRecordID, ColumnChanged, OldValue, NewValue)
SELECT @PKRecordID, 'COL3', @COL3_OLD, @COL3
WHERE EXISTS (SELECT @COL3 EXCEPT SELECT @COL3_OLD)
INSERT HistoryTable (PKRecordID, ColumnChanged, OldValue, NewValue)
SELECT @PKRecordID, 'COL4', @COL4_OLD, @COL4
WHERE EXISTS (SELECT @COL4 EXCEPT SELECT @COL4_OLD)
INSERT HistoryTable (PKRecordID, ColumnChanged, OldValue, NewValue)
SELECT @PKRecordID, 'COL5', @COL5_OLD, @COL5
WHERE EXISTS (SELECT @COL5 EXCEPT SELECT @COL5_OLD)
UPDATE TempTable
SET Success = 'Y'
WHERE TempTableID = @TempTableID
END
ELSE
BEGIN
INSERT MasterTable (PKRecordID, COL1, COL2, COL3, COL4, COL5)
SELECT @PKRecordID, @COL1, @COL2, @COL3, @COL4, @COL5
UPDATE TempTable
SET Success = 'Y'
WHERE TempTableID = @TempTableID
END
END TRY
BEGIN CATCH
INSERT ErrorTable (PKRecordID, TableName, TablePK, ErrorDateTime, ErrorCode, ErrorMsg)
SELECT @PKRecordID, 'TempTable', @TempTableID, GETDATE(), ERROR_NUMBER(), ERROR_MESSAGE()
END CATCH
FETCH NEXT FROM temp_cursor
INTO @TempTableID, @PKRecordID, @COL1, @COL2, @COL3, @COL4, @COL5
END
CLOSE temp_cursor;
DEALLOCATE temp_cursor;
-- VIEW OUTPUT
SELECT * FROM MasterTable
SELECT * FROM ErrorTable
SELECT * FROM HistoryTable
SELECT * FROM TempTable
对于这种类型的审计,你不应该需要一个光标,根据SQL Server的什么味道你你应该能够使用输出子句http://msdn.microsoft.com/en-us/library/ms177564.aspx – gh9
你没有指定哪些是TEMPTABLE和MASTERTABLE中的主键(即使有不任何定义的主键,我们需要知道哪些列应被视为主键的一部分)。此外,TEMPTABLE中的列数多于MASTERTABLE;我们应该忽略额外的列吗? –