2013-10-21 45 views
0

我有一个SQL Server 2008的表与两个XML列和以下结构:从柱A插入的SQL Server XML节点到塔B

JOB_ID int, 
RECORD_NO int, 
SOURCE_DATA xml, 
TARGET_DATA xml 

某些样本数据:

JOB_ID RECORD_NO SOURCE_DATA         TARGET_DATA 
------ --------- -------------------------------------------- ---------------- 
    1   1 <data><field id="C_ID">1684</field>...</data> <data/> 
    1   2 <data><field id="C_ID">9817</field>...</data> <data/> 
    1   3 <data><field id="C_ID">6508</field>...</data> <data/> 

根<数据> SOURCE_DATA中的节点保证有一组已知的子节点<字段>节点,每个子节点由“id”属性唯一标识。例如,一个典型的行可能包含SOURCE_DATA列,看起来像这样:

<data> 
    <field id="C_ID">1684</field> 
    <field id="C_FNAME">John</field> 
    <field id="C_LNAME">Doe</field> 
    <field id="C_ADDR1">123 Elm Street</field> 
    <field id="C_ADDR2"/> 
    <field id="C_CITY">Greenville</field> 
    <field id="C_STATE">NC</field> 
</data> 

我需要在SOURCE_DATA >节点复制<字段作为TARGET_DATA列的<数据>柱的孩子,但有不同的“ ID“属性值。例如,以上所示的SOURCE_DATA值就需要像这样在同一行中TARGET_DATA:

<data> 
    <field id="Q1">1684</field> 
    <field id="Q2">John</field> 
    <field id="Q3">Doe</field> 
    <field id="Q4">123 Elm Street</field> 
    <field id="Q5"/> 
    <field id="Q6">Greenville</field> 
    <field id="Q7">NC</field> 
</data> 

编辑补充:有一个在SOURCE_DATA列的字段ID字段ID的外部预定义的映射在TARGET_DATA列中,所以不能假定TARGET_DATA中的字段ID具有有序的升序。例如,TARGET_DATA列可以很容易地是这样的:

<data> 
    <field id="Q43_1">1684</field> 
    <field id="Q8">John</field> 
    <field id="Q9">Doe</field> 
    <field id="Q15_1">123 Elm Street</field> 
    <field id="Q15_2"/> 
    <field id="Q17_1">Greenville</field> 
    <field id="Q17_A_1">NC</field> 
</data> 

现在肯定的是,我能行集拖累我的C#的客户,在本地处理XML,然后进行一系列的更新,但除了是带宽密集型我正在处理100,000多行,因此需要很长的时间。

我一直在撞墙,试图弄清楚如何在一个操作中完成这个服务器端(甚至是一系列的语句,这可能是必要的,因为有一个外部映射的字段ID必须在传输过程中应用)与某种形式的select-select-select语法,但SQL Server XML DML命令似乎不想处理除字符串文字之外的任何内容(或者更可能是我没有看到怎么做)。

任何关于如何将SQL Server 2008屈服于我的意见将会得到愉快和感激的赞赏!

回答

1

试试这个:

declare @t table(SOURCE_DATA xml, TARGET_DATA xml) 

insert @t values('<data> 
    <field id="C_ID">1684</field> 
    <field id="C_FNAME">John</field> 
    <field id="C_LNAME">Doe</field> 
    <field id="C_ADDR1">123 Elm Street</field> 
    <field id="C_ADDR2"/> 
    <field id="C_CITY">Greenville</field> 
    <field id="C_STATE">NC</field> 
</data>', null) 


update @t 
set TARGET_DATA = 
SOURCE_DATA.query(' 
<data> 
{for $field in data/field 
    return 
     <field id="{concat("Q", xs:string(count(/data/field[. << $field]) + 1))}"> 
      {$field/text()} 
     </field> 
}  
</data> 
') 

select * 
from @t 

输出:

<data> 
    <field id="Q1">1684</field> 
    <field id="Q2">John</field> 
    <field id="Q3">Doe</field> 
    <field id="Q4">123 Elm Street</field> 
    <field id="Q5" /> 
    <field id="Q6">Greenville</field> 
    <field id="Q7">NC</field> 
</data> 
+0

谢谢,但不幸的是这是行不通的。我应该明确指出,SOURCE_DATA列中的字段ID与TARGET_DATA列中的字段ID有外部预定义的映射关系。解决方案假定,TARGET_DATA列中的ID不一定是数字部分中的顺序。我必须在我的问题中澄清。 – scottg

+0

但是,您的答案确实为我提供了一些有关如何解决此问题的建议,所以谢谢! – scottg

+0

@scottg,从你的问题中不清楚哪些数据包含'TARGET_DATA'列。你能否在更新后提供原始的'SOURCE_DATA',原始的'TARGET_DATA'和最终的'TARGET_DATA'。 –