2

日付フィールドの時刻が不正確な xml ドキュメントが SQL Server テーブルの xml 列に格納されています。

ドキュメント内のすべての日付と時刻 (SaleDateTime、LineStartTime、LineEndTime) の値を 15 秒ずつ更新したいので、たとえば、2012-02-01T00:07:50 は 2012-02-01T00:08:05 になります (なぜこのようにする必要があるのか​​については長い話です; それは私の手に負えません)。1 つ以上のトランザクションが存在する可能性があり、各トランザクションには 1 つ以上の行エントリを含めることができます。

DATEADD を使用して OPENXML やメソッドの変更などを試しましたが、うまくいきません。私は途方に暮れています。どんな助けでも大歓迎です。前もって感謝します!!

サンプルは以下

CREATE TABLE XMLTable (doc xml);

INSERT INTO XMLTable (doc)
VALUES
(
'<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Transaction>
  <SaleID>1</SaleID>
  <Sale>
    <SaleDateTime>2012-02-01T00:07:00</SaleDateTime>
    <LineItem>
      <Line>1</Line>
      <LineStartTime>2012-02-01T00:07:00</LineStartTime>
      <LineEndTime>2012-02-01T00:07:00</LineEndTime>
          <Amount>13.50</Amount>
    </LineItem>
  </Sale>
</Transaction>
<Transaction>
  <SaleID>2</SaleID>
  <Sale>
    <SaleDateTime>2012-02-01T00:11:00</SaleDateTime>
    <LineItem>
      <Line>1</Line>
      <LineStartTime>2012-02-01T00:11:00</LineStartTime>
      <LineEndTime>2012-02-01T00:11:00</LineEndTime>
          <Amount>13.50</Amount>
    </LineItem>
    <LineItem>
      <Line>2</Line>
      <LineStartTime>2012-02-01T00:11:00</LineStartTime>
      <LineEndTime>2012-02-01T00:11:00</LineEndTime>
          <Amount>5.22</Amount>
    </LineItem>
  </Sale>
</Transaction>
</Root>')

SELECT * FROM XMLTable 
4

3 に答える 3

1

メソッドを使用できますmodify。たとえば、最初に出現した を置き換えるにはSaleDateTime:

declare @now datetime = getdate()

update  XMLTable
set     doc.modify('replace value of (/Root/Transaction/Sale/SaleDateTime/text())[1] 
                    with sql:variable("@now")') 
于 2013-05-04T14:47:05.340 に答える
0

これらの XML ドキュメントがそれほど大きくない場合、またはこれが 1 回限りのものでパフォーマンスが優先されない場合は、ドキュメントを varchar としてキャストし、それに対して を実行しREPLACEて日付をインクリメントできます。

以下に例を示します (これを関数でラップすることもできます)。

declare @doc xml = 
'<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Transaction>
  <SaleID>1</SaleID>
  <Sale>
    <SaleDateTime>2012-02-01T00:07:00</SaleDateTime>
    <LineItem>
      <Line>1</Line>
      <LineStartTime>2012-02-01T00:07:00</LineStartTime>
      <LineEndTime>2012-02-01T00:07:00</LineEndTime>
          <Amount>13.50</Amount>
    </LineItem>
  </Sale>
</Transaction>
<Transaction>
  <SaleID>2</SaleID>
  <Sale>
    <SaleDateTime>2012-02-01T00:11:00</SaleDateTime>
    <LineItem>
      <Line>1</Line>
      <LineStartTime>2012-02-01T00:11:00</LineStartTime>
      <LineEndTime>2012-02-01T00:11:00</LineEndTime>
          <Amount>13.50</Amount>
    </LineItem>
    <LineItem>
      <Line>2</Line>
      <LineStartTime>2012-02-01T00:11:00</LineStartTime>
      <LineEndTime>2012-02-01T00:11:00</LineEndTime>
          <Amount>5.22</Amount>
    </LineItem>
  </Sale>
</Transaction>
</Root>'

declare @New xml = @doc;

;with 
dates (LineStartTime, LineEndTime) as
    (   -- get the start/end dates in any LineItem
        select  p.n.value('(LineStartTime)[1]', 'datetime'),
                p.n.value('(LineEndTime)[1]', 'datetime')
        from    @doc.nodes('Root/Transaction/Sale/LineItem')p(n)
    ),
upd (OldValue, NewValue) as
    (   -- add 15 min to each, and cast as varchar
        select  '<LineStartTime>' + convert(varchar, LineStartTime, 126) + '</LineStartTime>', 
                '<LineStartTime>' + convert(varchar, dateadd(mi, 15, LineStartTime), 126) + '</LineStartTime>'
        from    dates 
        union 
        select  '<LineEndTime>' + convert(varchar, LineEndTime, 126) + '</LineEndTime>', 
                '<LineEndTime>' + convert(varchar, dateadd(mi, 15, LineEndTime), 126) + '</LineEndTime>' 
        from    dates
    )
-- cast @doc as varchar, and replace each occurrence of start/end elements with NewValue
select  @new = cast(replace(cast(@new as varchar(max)), OldValue, NewValue) as xml)
from    upd;

select [Old]=@doc, [New]=@new;
于 2013-05-04T15:48:18.597 に答える