2015-04-23 41 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