2009-01-20 84 views
0

我需要遍歷表中的字段,並在其值不等於其默認值時執行某些操作。SQL Server比較字段值與其默認值

我在觸發器中,所以我知道表名。

select @field = 0, @maxfield = max(ORDINAL_POSITION) from 
INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName 

while @field < @maxfield 
begin 
... 

然後我就可以通過循環獲得的字段名稱在每次迭代:

select @fieldname = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME = @TableName 
and ORDINAL_POSITION = @field 

而且我可以得到默認值,然後我通過每個 使用這個循環中的字段的循環列:

select @ColDefault = SUBSTRING(Column_Default,2,LEN(Column_Default)-2) 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE Table_Name = @TableName 
AND Column_name = @fieldname 

我有我需要的一切,但我不能看到如何然後比較2.由於 我沒有字段名稱爲常數,只有在一個變量中,我看不到 如何從「插入」表中取出值(記住我在觸發器中) 以便查看它是否與默認值相同(現在保存在 @ColDefault作爲varchar)。

回答

2

首先,請記住觸發器可以同時觸發多個記錄。如果我這樣做:

INSERT INTO dbo.MyTableWithTrigger 
    SELECT * FROM dbo.MyOtherTable 

然後我的觸發器MyTableWithTrigger將需要處理多個記錄。 「插入的」僞指令將不止有一條記錄。

說了這麼多,要比較的數據,你可以運行這樣的選擇語句:

DECLARE @sqlToExec VARCHAR(8000) 
SET @sqlToExec = 'SELECT * FROM INSERTED WHERE [' + @fieldname + '] <> ' + @ColDefault 
EXEC(sqlToExec) 

,將返回從插入pseudotable不匹配的默認設置中的所有行。這聽起來像是你想對這些行做些什麼,所以你可能想要做的是在你調用@sqlToExec字符串之前創建一個臨時表,而不是隻選擇數據,將它插入臨時表中。然後你可以使用這些行來做你需要的任何異常處理。

一個catch - 這個T-SQL只適用於數字字段。您可能需要爲不同類型的字段構建單獨的處理。你可能有varchars,數字,斑點等,你需要不同的方式來比較這些。

+0

無需擔心多次插入,即可處理,但始終值得警告。我想我可能不得不開始使用臨時表,我會調查該選項。 – 2009-01-20 12:24:42

2

我懷疑你可以使用和exec來做到這一點。

但爲什麼不只是代碼生成一次。它將更具性能