2015-03-13 85 views
1

存在一個存儲過程,其中包含許多UPDATE(對於許多表)。 我需要做一些事情來記錄這個更新,但是沒有觸發器在SQL Server中對SELECT查詢結果進行復雜處理

很容易讓SP取一行+表名並將記錄添加到日誌表中。而且用更新的記錄形成SELECT也很容易。

我希望能夠找到像做

MAKE_LOG 
FROM (
    SELECT "tblName", EventID, ID 
    FROM ... 
) 

「MAKE_LOG」的方式 - 僅僅是一個例子名。我正在尋找使用存儲過程處理表的方法。也許,像表值參數。並且最好找到與SQL Server 2005兼容的東西。

我可以使用遊標,但語法看起來並不真正簡潔(可能我應該把它放到函數中)。

也許,還有另一種方法可以做到嗎?

回答

2

試試這個:

CREATE PROCEDURE spLog 
AS 
SELECT * FROM #log 
GO 


DECLARE @t1 TABLE(ID INT IDENTITY(1, 1), Name NVARCHAR(MAX)) 
DECLARE @t2 TABLE(ID INT IDENTITY(1, 1), Name NVARCHAR(MAX)) 
create TABLE #log (ID INT, TableName NVARCHAR(MAX), Act NVARCHAR(MAX)) 

INSERT INTO @t1 
OUTPUT Inserted.ID, '@t1', 'INSERT' INTO #log 
VALUES('Table1 Value1') 

INSERT INTO @t2 
OUTPUT Inserted.ID, '@t2', 'INSERT' INTO #log 
VALUES('Table2 Value1') 

INSERT INTO @t1 
OUTPUT Inserted.ID, '@t1', 'INSERT' INTO #log 
VALUES('Table1 Value2') 

UPDATE @t2 
SET Name = 'New Name' 
OUTPUT Inserted.ID, '@t2', 'UPDATE' INTO #log 

DELETE 
FROM @t1 
OUTPUT deleted.ID, '@t1', 'DELETE' INTO #log 

EXEC dbo.spLog 

DROP TABLE #log 

輸出:

ID TableName Act 
1 @t1   INSERT 
1 @t2   INSERT 
2 @t1   INSERT 
1 @t2   UPDATE 
1 @t1   DELETE 
2 @t1   DELETE 

從2008年起,您可以創建用戶定義的表型,填充它,並傳遞給存儲proc:

CREATE TYPE LogTableType AS TABLE 
(
    ID INT, 
    TableName NVARCHAR(MAX), Act NVARCHAR(MAX) 
) 
GO 

CREATE PROCEDURE spLog 
@Log LogTableType READONLY 
AS 
SELECT * FROM @Log 
GO 


DECLARE @t1 TABLE(ID INT IDENTITY(1, 1), Name NVARCHAR(MAX)) 
DECLARE @t2 TABLE(ID INT IDENTITY(1, 1), Name NVARCHAR(MAX)) 
DECLARE @log LogTableType 

INSERT INTO @t1 
OUTPUT Inserted.ID, '@t1', 'INSERT' INTO @log 
VALUES('Table1 Value1') 

INSERT INTO @t2 
OUTPUT Inserted.ID, '@t2', 'INSERT' INTO @log 
VALUES('Table2 Value1') 

INSERT INTO @t1 
OUTPUT Inserted.ID, '@t1', 'INSERT' INTO @log 
VALUES('Table1 Value2') 

UPDATE @t2 
SET Name = 'New Name' 
OUTPUT Inserted.ID, '@t2', 'UPDATE' INTO @log 


DELETE 
FROM @t1 
OUTPUT deleted.ID, '@t2', 'DELETE' INTO @log 

EXEC dbo.spLog @log 
+0

看起來像很好的解決方案!我猜有沒有辦法在** SQL Server 2005 **(我的意思是表值SP)中做類似的事情? – 2015-03-13 13:37:14

+0

@TimushevRoman,不幸的是。 – 2015-03-13 13:51:18

1

我不太清楚你的建議是什麼,但它看起來像你想包裝一堆SQL語句,並以某種方式奇蹟般地記錄變化......這確實是魔法。

相反,按照您在問題中提出的建議進行操作,並創建一個存儲過程,您只需傳遞一些參數即可爲其插入日誌條目。然後在每次更新後調用它。

樣品:

CREATE PROCEDURE [dbo].[InsertLogEntry] 
    @UserId INT = NULL , 
    @Table NVARCHAR(256) , 
    @EventId INT , 
    @Id INT 
AS 
    BEGIN 
     SET NOCOUNT ON 

     INSERT INTO LogTable 
       (UserId, [Table], EventId, Id) 
     VALUES (@UserId, @Table, @EventId, @Id) 
    END 
+0

是的,這是如何更新一行的方法。但如何應用它,如果UPDATE基於大子集的SELECT(通常是這樣)呢? – 2015-03-13 12:32:32