0

DB に更新が必要な XML がいくつかあります。それらの単純化された表現は次のとおりです。

<root>
  <child1>blah</child1>
</root>

<child1>次のような構造を取得するには、別の要素でラップする必要があります。

<root>
  <child1Root>
    <child1>blah</child1>
  </child1Root>
</root>

簡単そうに見えますが、私は T-SQL と DML のスペシャリストではありません。

注: 更新する理由を知りたい場合の答えは、以下の XML は DataContractSerializer を使用して逆シリアル化できないということです。XmlSerializer および XmlArray 属性を使用して逆シリアル化できますが、DCS は使用できません。

<root>
  <child1>blah</child1>
  <child2>blah</child2>
</root>
4

3 に答える 3

2

実際のコードが例と同じくらい単純な場合は、次のようにするだけです。

DECLARE @yourTable TABLE ( yourXML XML )

INSERT INTO @yourTable ( yourXML )
VALUES 
    ( '<root><child1>blah1</child1></root>' ),
    ( '<root><child1>blah2</child1></root>' )

UPDATE @yourTable
SET yourXML = yourXML.query('root/child1').query('<root><child1Root>{.}</child1Root></root>') 

SELECT * FROM @yourTable

実際の XML がもう少し複雑な場合は、分割する必要があるかもしれません。

于 2012-09-18T13:32:36.580 に答える
0

ここに作業サンプルがあります。有効な XML には厳密な規則があるため、文字列操作が機能しない理由は思い浮かびません。少なくとも、文字列検索のキーとなる「<」は、XML タグ名の外に存在してはなりません。

-- create a sample table variable with a few variations
declare @T table (sample xml)
insert @T select '
<root>
  <child1>blah</child1>
</root>'
insert @T select '
<root>
  <child1>blah1</child1>
  <child1>blah2</child1>
</root>'
insert @T select '
<root>
  <child1>
    blah1
    <child2>blah2</child2>
  </child1>
</root>'
insert @T select '
<root>
<child0>
  <child1>
    <child4>
      <child3>blah2</child3>
    </child4>
  </child1>
</child0>
</root>'

-- peek at the content
select * from @T

-- perform the replacements as many times as required
-- note that the string "stackoverflow123" is expected to NEVER
--    exist in your data, or use another string if it does!
while @@rowcount > 0
begin
    update T
    set sample = stuff(X.A, Y.B, Z.C - Y.B + 9, '<child1Root>'+
        replace(replace(
            SUBSTRING(X.A, Y.B, Z.C - Y.B + 9),
            '<child1>','<stackoverflow123>'),
            '</child1>','</stackoverflow123>')
                +'</child1Root>')
    from @T T
    cross apply (
        select convert(varchar(max),sample)) X(A)
    cross apply (
        select patindex('%<child1>%</child1>%', X.A)) Y(B)
    cross apply (
        select charindex('</child1>', X.A, Y.B+1)) Z(C)
    where Z.C > 0
end

-- finally revert the placeholder string back to "child1"
update @T
set sample = replace(convert(varchar(max),sample), 'stackoverflow123', 'child1')

-- inspect the finished product
select * from @T
于 2012-09-18T02:25:04.040 に答える
0

ブルート フォース アプローチ:

DECLARE @myDoc xml       
SET @myDoc = '
<root>       
    <child1>blah</child1>       
</root>'       
SELECT @myDoc       

DECLARE @child1 xml;
SET @child1 = @myDoc.query('/root/child1')
SELECT @child1

SET @myDoc.modify('       
insert <child1Root />
into (/root)[1]') 
SELECT @myDoc       

SET @myDoc.modify('       
insert sql:variable("@child1")
into (/root/child1Root)[1]') 
SELECT @myDoc       

SET @myDoc.modify('       
delete /root/child1') 
SELECT @myDoc       
于 2012-09-17T21:42:59.890 に答える