簡體   English   中英

使用SQL查詢編輯XML SQL Server 2008 R2

[英]Edit XML with SQL query SQL Server 2008 R2

我有以下問題,希望有人可以提供幫助。

我有一個具有數千行的SQL Server數據庫。 每行包括一個具有ID的列和一個具有XML數據的列。

此XML數據如下所示:

<record id="1">
 <field tag="aa" occ="1" lang="nl-NL" invariant="false">Jan</field>
 <field tag="aa" occ="1" lang="en-US" invariant="false">John</field>
 <field tag="aa" occ="1" lang="de-DE" invariant="false">der Jan</field>
 <field tag="aa" occ="2" lang="nl-NL" invariant="false">Jan2</field>
 <field tag="aa" occ="2" lang="en-US" invariant="false">John2</field>
 <field tag="ab" occ="1">Something</field>
 <field tag="ac" occ="1" lang="de-DE" invariant="false">Rechnung</field>
 <field tag="ac" occ="1" lang="nl-NL" invariant="false">rekening</field>
 <field tag="ad" occ="1">Something2</field>
 <field tag="ae" occ="1" lang="nl-NL" invariant="false">stoeptegel</field>
</record>

我想根據以下規則為每個記錄編輯此XML:

  1. 對於每個唯一的occ(出現率),標記組合只能為1 @invariant屬性為true
  2. 如果具有@ lang = zh-CN屬性,則@invariant必須為'true'。 其余字段具有相同的occ,標記組合必須保持為“ false”。 (如示例代碼中的標簽aa)
  3. 如果a具有@ lang = nl-NL屬性,但沒有@ lang = en-US,則對於'nl-NL',@invariant必須為'true'。 其余字段具有相同的occ,標記組合必須保持為“ false”。 (例如示例代碼中的標簽ac)
  4. 如果一個occ,標記組合只有一個實例,則@invariant必須為“ true”。 因此獨立於@lang值。 (例如示例代碼中的標簽ae)

運行1個或多個SQL查詢后,代碼應如下所示:

<record id="1">
 <field tag="aa" occ="1" lang="nl-NL" invariant="false">Jan</field>
 <field tag="aa" occ="1" lang="en-US" invariant="true">John</field>
 <field tag="aa" occ="1" lang="de-DE" invariant="false">der Jan</field>
 <field tag="aa" occ="2" lang="nl-NL" invariant="false">Jan2</field>
 <field tag="aa" occ="2" lang="en-US" invariant="true">John2</field>
 <field tag="ab" occ="1">Something</field>
 <field tag="ac" occ="1" lang="de-DE" invariant="false">Rechnung</field>
 <field tag="ac" occ="1" lang="nl-NL" invariant="true">rekening</field>
 <field tag="ad" occ="1">Something2</field>
 <field tag="ae" occ="1" lang="nl-NL" invariant="true">stoeptegel</field>
</record>

我的問題是根據上述規則創建正確的SQL查詢,以替換所有記錄的所有節點。

到目前為止,我想到了這個:

while exists 
(
select * 
from databasetable 
where xmlcolumn.exist('/record/field/@invariant[.="false"]') = 1
)

update databasetable
set xmlcolumn.modify
('replace value of (/record/field/@invariant[.="false"])[1] with "true"')

它將@invariant的每個值編輯為'true'。

有人可以幫我建立正確的查詢嗎? 提前致謝!

切碎您的XML,並使用帶有order by子句的row_number() ,該子句首先對en-US進行排序,然后對nl-NL進行排序。
使用第二個row_number()為每一行(ID和RowNumber)生成一個唯一鍵。
將值存儲在表變量中。
獲取最大行號,並為每個行號更新XML ia循環。

declare @Tmp table
(
  ID int, -- Primary key in databasetable
  RowNumber int,
  Tag varchar(2),
  Occ int,
  Lang varchar(5),
  Invariant bit
  primary key (ID, RowNumber)
);

with C1 as
(
  select T.ID, -- Primary key in databasetable
         R.F.value('@tag', 'varchar(2)') as Tag,
         R.F.value('@occ', 'int') as Occ,
         R.F.value('@lang', 'varchar(5)') as Lang
  from databasetable as T
    cross apply T.xmlcolumn.nodes('/record/field') as R(F)
), 
C2 as
(
  select ID, Tag, Occ, Lang,
         row_number() over(partition by ID order by (select 0)) as RowNumber,
         row_number() over(partition by ID, Tag, Occ 
                           order by case Lang 
                                      when 'en-US' then 1
                                      when 'nl-NL' then 2
                                      else 3
                                    end) as rnInv
  from C1
)
insert into @Tmp (ID, RowNumber, Tag, Occ, Lang, Invariant)
select ID, RowNumber, Tag, Occ, Lang, case rnInv when 1 then 1 else 0 end
from C2;

declare @MaxRowNum int;
declare @I int = 1;

select @MaxRowNum = max(RowNumber)
from @Tmp;

while @I <= @MaxRowNum
begin
  update T
  set xmlcolumn.modify('replace value of (/record/field[@tag = sql:column("Tmp.Tag") and
                                                        @occ = sql:column("Tmp.Occ") and
                                                        @lang = sql:column("Tmp.Lang")]/@invariant)[1] 
                          with sql:column("Tmp.Invariant")')
  from databasetable as T
    inner join @Tmp as Tmp
      on T.ID = Tmp.ID
  where Tmp.RowNumber = @I;

  set @I += 1;
end

這里可以找到工作樣本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM