2015-04-23 39 views
1

使用SQL Server 2008-SQL Server的XQuery的XML索引

我有存储在我的表中的列是出口一些图纸信息的结果XML数据:

<layout> 
    <config> 
     <graphic_type>Box</graphic_type> 
     <data_access> 
     </data_access> 
     <data> 
      <dimension x="1" y="2" z="3" /> 
      <curve_info ir="-1.5" or="1.5" degree="0"/> 
      <position x="4" y="5" z="6" /> 
      <rotation x="7" y="8" z="9" /> 
      <color>FFD3D3D3</color> 
      <is_position_relative>false</is_position_relative> 
     </data> 
    </config> 
    <config> 
     ... 
    </config> 
</layout> 

凡到数画个人作品是未知的。 目前,如果我想要做类似沿X轴移动整个图纸100个单位,我有SQL代码,如:

SET @xTrans = 100 
UPDATE TableName 
SET xmlColumn.modify('replace value of (//data/position/@x)[1] with sql:variable("@xTrans")') 
SET xmlColumn.modify('replace value of (//data/position/@x)[2] with sql:variable("@xTrans")') 
SET xmlColumn.modify('replace value of (//data/position/@x)[3] with sql:variable("@xTrans")') 
... 
SET xmlColumn.modify('replace value of (//data/position/@x)[20] with sql:variable("@xTrans")') 

我基本上做到这一点的任意次数,因为我不知道每张图纸中实际存在多少个节点。 我对SQL相当陌生,对XQuery更是如此,但有没有更好的方法去解决这个问题?

为了扩展性更强,下一个问题是当设备在这个模型的顶部绘制时,它们最初是在2d中绘制的,然后导出到xml文件中,因此它们呈现高度值(恰好是在我的情况下,Y轴)的第一部分图纸,当设备X和Z坐标可能将其放置在整个图纸的末尾。这会导致某些设备在模型上方或下方浮动。我能想到这个问题写的唯一的事情是一样的东西:

-- Determine if moving along X or Z axis by Y rotation 
-- If its the Z-axis, find the range that section covers with position+dimension 
    -- @range = (///position/@z)[1] + (///dimension/@z)[1] 
-- See if the device falls in that range 
    -- If (///position/@z)[1] < device position @z < @range 
-- Then we need the rotation of that box in the Z-axis 
-- to calculate the height change for the device 

但是,这将涉及不必复制并粘贴代码〜15倍(我不知道什么组件模型的数量最多可能有,我在当前项目中看到了6),并改变了效率极低的索引[1]。

设备XML布局与模型完全相同,只是具有不同的值。

回答

1

无法在SQL Server的xml中一次替换多个值,因此有several options。在你的情况下,我建议使用简单的循环:

select @i = max(t.xmlColumn.value('count(//data/position[@x != 100])', 'int')) 
from TableName as t 

while @i > 0 
begin 
    update TableName set 
     xmlColumn.modify(' 
      replace value of (//data/position[@x != 100])[1]/@x 
      with sql:variable("@xTrans")' 
     ) 

    set @i = @i - 1 
end