我问this question这导致我做了以下事情。
这意味着我可以将复杂的对象数据传递给SQLServer并对哈希进行查找,而不是尝试粉碎并将XML与表匹配(我也可以这样做但是速度慢(呃))... < / p>
然而 - 关于XML的一个好处是你可以格式化它,例如缩进等等 - 而且 - 属性顺序并不重要。但是当您对某些格式和缩进进行哈希处理时很重要。所以我在C#中做的是......
这很好用,但是当我测试它时,格式化 XML更容易,所以我可以更容易地看到我传递给存储过程的内容。
如果可以信任SQLServer来保存属性顺序but it can't ...
,那就太好了不保留XML实例中的属性顺序。当你 查询存储在xml类型列中的XML实例的顺序 生成的XML中的属性可能与原始XML不同 实例
这意味着我无法使用SQLServer的XML数据类型来规范化数据。
让我感到困扰的是,某些人会在某个时候使用我的触发器并认为“哦,很棒,XML,属性顺序无关紧要,格式无关紧要,表示的数据是相同的“但是,当我哈希时,情况并非如此。
任何人都有解决这个问题的方法吗?我真的不想在T-SQL中编写XML解析器!或者使用其他人编写的XML解析器来规范化它。为什么SQLServer XML数据类型不能保留属性顺序?
我想我可以“信任”我的应用程序始终以相同的格式/顺序传递XML,从而导致相同对象的相同哈希。但我对于存储过程还必须“信任”应用程序来执行此操作的想法感到不安。我想以某种方式能够检查XML的规范化,它显然会更加健壮。
答案 0 :(得分:0)
我将尝试序列化存储过程中的对象。
让我们来讨论以下课程:
class MyCustomObject
{
int id;
string SomeField;
}
然后你可以使用一个存储过程,你在xml中序列化对象并计算输入参数的校验和,然后在另一个中你可以传递一个HashValue(校验和)和一个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