[英]how to change column name and change a value in a table via a stored procedure?
[英]How to find the table and column name affected by a stored procedure at runtime?
假設我的邏輯中有if else條件的存儲過程。 如果條件為真,則表示更新tableA,否則更新tableB。 我希望得到受其所有列影響的表名,其值根據運行存儲過程時發生的條件執行而更新。
這用於記錄目的,即哪個表,列受哪個存儲過程以及由誰影響。 我正在使用SQL Server 2008.如果您有任何建議,請告知我們。
有很多不同的記錄方法,但一種方法是使用觸發器。 請參閱SQL Server聯機文檔中的DML觸發器 。 創建一個日志表,然后在TableA和TableB上創建一個AFTER TRIGGER,以將適當的信息寫入日志表。
行級和列級跟蹤
更改跟蹤使應用程序能夠跟蹤用戶所做的所有更改,這是一種內置方法
SQL Server更改跟蹤確定列是否已更改,因此我決定使用下面的腳本在2008 R2中嘗試一下。 基本上在最后一個更新語句中,我將列更新為列中已存在的相同值。 SQL似乎只記錄該列涉及更新語句。 不幸的是,這意味着任何希望在列級執行同步操作的人都必須編寫更復雜的行更新邏輯。
CREATE TABLE [dbo].[Test](
[Id] [int] IDENTITY(1,1) NOT NULL,
[A] [varchar](50) NULL,
[B] [int] NULL
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER DATABASE TrackingTest
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON)
ALTER TABLE TrackingTest.dbo.Test
ENABLE CHANGE_TRACKING
WITH (TRACK_COLUMNS_UPDATED = ON);
GO
INSERT INTO dbo.Test (A,B) VALUES ('C', 50)
INSERT INTO dbo.Test (A,B) VALUES ('D', 50)
SELECT 'SYS_CHANGE_COLUMS = NULL means that all columns changed.'
SELECT
CT.Id, CT.SYS_CHANGE_OPERATION,
CT.SYS_CHANGE_COLUMNS, CT.SYS_CHANGE_CONTEXT,
CHANGE_TRACKING_IS_COLUMN_IN_MASK (COLUMNPROPERTY(OBJECT_ID('dbo.Test'), 'A', 'ColumnId'),CT.SYS_CHANGE_COLUMNS) AS A_CHANGED,
CHANGE_TRACKING_IS_COLUMN_IN_MASK (COLUMNPROPERTY(OBJECT_ID('dbo.Test'), 'B', 'ColumnId'),CT.SYS_CHANGE_COLUMNS) AS B_CHANGED
FROM
CHANGETABLE(CHANGES dbo.Test, NULL) AS CT
DECLARE @synchronization_version BIGINT
SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();
SELECT * FROM dbo.Test
SELECT 'Changing both columns via "UPDATE dbo.Test SET A=''E'', B=51"'
UPDATE dbo.Test SET A='E', B=51
SELECT * FROM dbo.Test
SELECT
CT.Id, CT.SYS_CHANGE_OPERATION,
CT.SYS_CHANGE_COLUMNS, CT.SYS_CHANGE_CONTEXT,
CHANGE_TRACKING_IS_COLUMN_IN_MASK (COLUMNPROPERTY(OBJECT_ID('dbo.Test'), 'A', 'ColumnId'),CT.SYS_CHANGE_COLUMNS) AS A_CHANGED,
CHANGE_TRACKING_IS_COLUMN_IN_MASK (COLUMNPROPERTY(OBJECT_ID('dbo.Test'), 'B', 'ColumnId'),CT.SYS_CHANGE_COLUMNS) AS B_CHANGED
FROM
CHANGETABLE(CHANGES dbo.Test, @synchronization_version) AS CT
SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();
SELECT * FROM dbo.Test
SELECT 'Only setting column A to the value already in the column via "UPDATE dbo.Test SET A=''E''"'
UPDATE dbo.Test SET A='E'
SELECT * FROM dbo.Test
SELECT 'Now SYS_CHANGE_COLUMS has a value showing that only A was changed'
SELECT 'To bad it isn''t smart enough to know that the data did not change!'
SELECT
CT.Id, CT.SYS_CHANGE_OPERATION,
CT.SYS_CHANGE_COLUMNS, CT.SYS_CHANGE_CONTEXT,
CHANGE_TRACKING_IS_COLUMN_IN_MASK (COLUMNPROPERTY(OBJECT_ID('dbo.Test'), 'A', 'ColumnId'),CT.SYS_CHANGE_COLUMNS) AS A_CHANGED,
CHANGE_TRACKING_IS_COLUMN_IN_MASK (COLUMNPROPERTY(OBJECT_ID('dbo.Test'), 'B', 'ColumnId'),CT.SYS_CHANGE_COLUMNS) AS B_CHANGED
FROM
CHANGETABLE(CHANGES dbo.Test, @synchronization_version) AS CT
Results are:
您需要在TableA
和TableB
上創建UPDATE triggers
。 以下是以下語法:
CREATE TRIGGER TriggerName
ON [dbo].[TableName]
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON
-- here goes your code
-- you can select updated values by following
SELECT *
FROM
inserted
INNER JOIN
deleted
ON inserted.PrimaryKey = deleted.PrimaryKey
-- Update is detected when is in both: deleted and inserted
END
UPDATE
因此,您可以從存儲過程中選擇更新的數據並將其插入臨時表。
CREATE PROCEDURE sp_example
@var1 INT,
@var2 NVARCHAR(40),
@var3 NVARCHAR(60)
AS
BEGIN
INSERT INTO ExampleTbl VALUES (@var1, @var2, @var3)
-- You could create temp table as shown below
CREATE TABLE #TempTbl
(
Id INT,
Name NVARCHAR(40),
Email NVARCHAR(60),
)
INSERT INTO #TempTbl VALUES (@var1, @var2, @var3)
SELECT * FROM #TempTbl
END
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.