2012-10-02 75 views
1

我問this question這導致我執行以下操作。正常化SQLServer中的哈希散列

  • 創建C#對象結構的XML表示形式,以便將它傳遞給SQLServer。
  • 創建一個存儲過程,其中散列XML,然後將XML分解成相關表,並將散列存儲在根表中以便快速查找。

這意味着我可以將複雜的對象數據傳遞給SQLServer並對哈希進行查找,而不是試圖將XML與表格匹配(我也可以這樣做,但速度很慢(er))。 ..

但是 - 關於XML的好處之一是,你可以格式化它,例如縮進等等 - 還有 - 那個屬性順序並不重要。但是當你散列格式和縮進是重要的。所以,我做什麼,在C#是...

  • 通過將所有屬性按字母順序
  • 使用的ToString(DisableFormatting)去除多餘的空格的格式

也能正常工作規範化XML,但是當我測試時,格式化爲 XML會更容易,所以我可以更輕鬆地看到我傳遞給存儲過程的內容。

這將是很好,如果SQLServer的可以信任保存屬性順序but it can't ...

屬性的XML實例的順序不會保留。當您查詢存儲在xml類型列中的XML實例時,結果XML中的 屬性的順序可能與原始XML 實例不同。

這意味着我不能使用SQLServer的XML數據類型來規範化數據。

什麼讓我困惑的是,在某些時候有人會使用我的特效,並認爲「哦,太好了,XML,屬性順序無所謂,格式無關緊要,所表示的數據是相同的」當我哈希這不會是這種情況。

任何人都可以解決這個問題嗎?我真的不想在T-SQL中編寫XML解析器!或者使用其他人編寫的XML解析器來標準化它。爲什麼SQLServer XML數據類型不能保存屬性順序?

我想我可以「信任」我的應用程序始終以相同的格式/順序傳遞XML,從而爲相同的對象產生相同的散列。但我對存儲過程也必須「信任」應用程序來實現這一點的想法感到不舒服。我想以某種方式能夠檢查XML的規範化,它顯然會更加健壯。

+0

雖然SQL Server分析/正常化過程可能不完全建立的結果與c#相同的XML,它至少是一致的。在散列之前,您不能依賴這種一致性來處理XML嗎? – paul

+0

@paul嗯,對於我的實際應用目的是的。但是如果有人想要查看是否存在特定的記錄,並且他們手動或從另一個應用程序調用proc或某種格式化的XML,那麼他們可能會認爲它實際上不會,然後我最終可能會得到兩個語義相同的記錄與不同的散列 - 我想避免。 –

回答

0

我會嘗試序列化存儲過程中的對象。

讓我們supose以下類:

class MyCustomObject 
{ 
    int id; 
    string SomeField; 
} 

然後你可以使用,你序列化對象一個XML格式的存儲過程和計算輸入參數的校驗和,然後在另外一個可以傳遞一個散列值(校驗和)和一個Xml。通過反序列化Xml可以計算Xml中字段的校驗和並將其與傳遞的HashValue進行比較。

試試這個代碼: (請注意,您應該存儲的哈希值並將其返回給調用者和做一些與XML)

CREATE PROCEDURE HashObject(@id int, @SomeField varchar(255)) AS 
BEGIN 
    SELECT 
     CHECKSUM(@id, @SomeField) AS CalculatedHashValue, 
     (SELECT @id AS ID, @SomeField AS SomeField FOR XML RAW('xmlRowName')) AS Xml_Data, 
     @id AS SPCall_ID, 
     @SomeField AS SPCall_SomeField 
END 
GO 

CREATE PROCEDURE CheckHash(@HashValue INT, @data XML) AS 
BEGIN 
    SELECT 
     CHECKSUM(rt.value('@ID', 'int'), rt.value('@SomeField', 'varchar(255)')) AS Xml_CalculatedHashValue, 
     @data Xml_Data, 
     rt.value('@ID', 'int') AS Xml_ID, 
     rt.value('@SomeField', 'varchar(255)') AS Xml_SomeField, 
     @HashValue AS SPCall_HashValue 

    FROM @data.nodes('xmlRowName') AS nd(rt) 

END 
GO 

DECLARE @id INT = 11 
DECLARE @SomeField varchar(255) = 'string value' 
DECLARE @data XML 

EXEC dbo.HashObject @id, @SomeField 

SET @data = (SELECT @id AS ID, @SomeField AS SomeField FOR XML RAW('xmlRowName')) 
EXEC dbo.CheckHash 0, @data 

SET @data = (SELECT 25 AS ID, 'diferent string value' AS SomeField FOR XML RAW('xmlRowName')) 
EXEC dbo.CheckHash 0, @data 
GO 
+0

感謝您的回答。我不知道如何將這個解決方案應用到我的情況(請參閱[這個問題])(http://stackoverflow.com/questions/12674327/quickest-method-for-matching-nested-xml-data-against-database -table-structure)) - 我可以讓我的內部元素重複任意次數。我需要將.Net中的數據作爲XML傳遞給SQLServer,但我希望屬性順序和格式與哈希值無關。 –