2015-03-13 25 views
0

我有一個觸發器,從inserted表取柱(和它們的值),並插入它們作爲文本在審計表,例如:將非varchar列寫入文本列時CAST是否必需?

INSERT INTO audit 
    (tablename, changes) 
SELECT 
    'mytable', 
    'id=' + cast(id as nvarchar(50) + ';name=' + name + ';etc...' 
FROM 
    inserted 

我有最列是非VARCHAR大表。爲了將它們連接成一個字符串,我需要投射每一列。

是否有必要這樣做?有沒有更好的辦法?

question中的第二個(未標記的答案)巧妙地使用xml和cross apply連接值。

有沒有辦法將它擴大到包括列名,這樣最終的結果將是:

'id=1;name=myname;amount=100;' etc.... 

回答

1

是的,你需要非字符數據轉換爲字符串之前,您可以連接它。您可能希望使用CONVERT來代替易受區域格式化影響的數據(我特意在此考慮日期)以確保您獲得確定性結果。您還需要處理可爲空的列,即ISNULL(CAST(MyColumn AS VARCHAR(100)), '') - 如果連接NULL,它將使整個字符串爲空。

+0

另一個解決方案是'SET CONCAT_NULL_YIELDS_NULL OFF',所以如果有'NULL',字符串仍然會被連接在一起。 – 2015-03-13 08:23:51

+0

@EvaldasBuinauskas好點,但[CONCAT_NULL_YIELDS_NULL](https://msdn.microsoft.com/en-us/library/ms176056.aspx)已被棄用,因此建議不要在新工作中使用它。 – 2015-03-13 08:26:53

1

爲什麼不把它保存爲xml

select * from inserted for xml auto 

它通常需要更少的空間不是一個簡單的text列,你可以把它當作(相對)歸一化數據。最重要的是,您不必手動處理所有複雜的東西(您的代碼如何處理結束語,引號......)。

實際上,您甚至可以將索引添加到xml列中,因此甚至可以通過搜索實用。即使沒有索引,它的搜索速度也會更快。所有記錄在mytable中更改爲name某些值。

當然,您可以保留相同的所有您的審計表的代碼 - 無需保持它們與表結構等同步(除非您只想選擇一些明確的列,當然)。

+0

我會採取這種方法,但目前的審計表使用上述格式,它包含數以百萬計的記錄。 – 2015-03-13 08:56:44

相關問題