Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 根据数据库表结构匹配嵌套XML数据的最快方法_Sql_Sql Server 2005_Data Structures_Orm - Fatal编程技术网

Sql 根据数据库表结构匹配嵌套XML数据的最快方法

Sql 根据数据库表结构匹配嵌套XML数据的最快方法,sql,sql-server-2005,data-structures,orm,Sql,Sql Server 2005,Data Structures,Orm,我有一个创建数据请求的应用程序,它可能非常复杂。这些需要作为表存储在数据库中。datarequest(作为XML)的概要是 <datarequest> <datatask view="vw_ContractData" db="reporting" index="1"> <datefilter modifier="w0"> <filter index="1" datatype="d" column="Contract Date" p

我有一个创建
数据请求的应用程序,它可能非常复杂。这些需要作为表存储在数据库中。
datarequest
(作为XML)的概要是

<datarequest>
  <datatask view="vw_ContractData" db="reporting" index="1">
    <datefilter modifier="w0">
      <filter index="1" datatype="d" column="Contract Date" param1="2009-10-19 12:00:00" param2="2012-09-27 12:00:00" daterange="" operation="Between" />
    </datefilter>
    <filters>
      <alternation index="1">
        <filter index="1" datatype="t" column="Department" param1="Stock" param2="" operation="Equals" />
      </alternation>
      <alternation index="2">
        <filter index="1" datatype="t" column="Department" param1="HR" param2="" operation="Equals" />
      </alternation>
      </filters>
    <series column="Turnaround" aggregate="avg" split="0" splitfield="" index="1">
      <filters />
    </series>
    <series column="Requested 3" aggregate="avg" split="0" splitfield="" index="2">
      <filters>
        <alternation index="1">
          <filter index="1" datatype="t" column="Worker" param1="Malcom" param2="" operation="Equals" />
        </alternation>          
      </filters>
    </series>
    <series column="Requested 2" aggregate="avg" split="0"  splitfield="" index="3">
      <filters />
    </series>
    <series column="Reqested" aggregate="avg" split="0" splitfield="" index="4">
      <filters />
    </series>
  </datatask>
</datarequest>

这将对数据请求进行编码,该数据请求包括日期范围、主筛选器、系列和系列筛选器。基本上,任何具有
索引
属性的元素都可以在其父元素中多次出现-例外情况是
日期过滤器中的
过滤器

但这种结构是学术性的,问题更为根本:

当请求通过时,像这样的XML将作为存储过程的参数发送到SQLServer。该XML被分解成一个非规范化的表,然后迭代地写入规范化的表,如
tblDataRequest(DataRequestID PK)
tblDataTask
tblFilter
tblSeries
。这很好

当我想将给定的XML定义与数据库中已有的定义进行匹配时,就会出现问题。我现在是通过

  • 将XML分解到非规范化的表中
  • 使用CTE将数据库中的所有现有数据拉入相同的非标准化形式
  • 使用巨大的
    WHERE
    条件进行匹配(34行长)
…这将返回与给定XML完全匹配的任何DataRequestID。我担心这种方法最终会慢得令人痛苦——部分原因是我不相信CTE会做任何巧妙的过滤,它会在应用巨大的
WHERE
之前每次都提取所有数据

我认为一定有更好的解决办法

  • 在存储
    数据请求时
    ,还要以某种方式存储数据请求的散列,并简单地匹配该散列。如果发生碰撞,请使用当前方法。然而,我想使用集合逻辑来实现这一点。此外,我还担心XML中不相关的小差异会改变散列-伪空间等
  • 以某种方式从下到上迭代执行匹配。例如,生成一个在最低级别匹配的过滤器列表。将其作为
中的
的一部分来匹配序列。将此作为
中的
的一部分,以匹配数据任务等。问题是,当我想得太久时,我开始昏厥


基本上-以前是否有人遇到过此类问题(他们一定遇到过)。那么,解决这个问题的推荐方法是什么呢?示例(伪)代码会很好:)

为了消除微小差异的可能性,我将通过XML转换(XSLT)运行请求

或者,因为您已经有了将其解析为非规范化的staging表的代码,这也很好。然后,我将简单地使用创建一个新的XML文档

这里的目标是创建一个标准化的XML文档,在适当的地方尊重顺序,并在不一致的地方消除不一致性

完成后,将其存储在新表中。现在,您可以运行“标准化”请求XML与现有数据的直接比较

要进行实际比较,可以使用散列,将XML存储为字符串并进行直接字符串比较,或者进行如下完整的XML比较:


只要XML不超过8000字节,我的首选方法是创建一个唯一的字符串(如果您有特殊的字符支持,可以是VARCHAR(8000)或NVARCHAR(4000)),并在列上创建一个唯一的索引。

我使用XML规范化(修剪和排序节点)和哈希处理类似的问题。它运行得很好,速度也很快。所以它首先解析XML,应用规范化,然后以一般方式计算哈希。@ViktorStolbin感谢您的评论。所以我还有希望!我不需要对节点进行排序,因为顺序很重要——尽管属性顺序并不重要。您对属性顺序进行了排序吗?我对所有内容进行了排序,因为XML是DB查询的直观表示,我依赖于DB查询优化。可能散列实现应该对元素顺序敏感。显然,SQLServer XML类型在作为
VARCHAR
传递到存储过程之前,我可能需要在应用程序端对XML进行排序。+1非常好的答案Rai!欢迎来到SO。顺便说一句,这个方法就是我如何解决这个问题的!