4

カーソルを使用せずに、行全体をXML変数に挿入するにはどうすればよいですか?私は私ができることを知っています

SET @errors.modify('insert <error>{ sql:variable("@text") }</error> as last into /errors[1]')

変数の値を挿入しますが、基本的にはやりたいです

SET @errors.modify(SELECT 'insert <error>{ sql:column("text") }</error>' FROM table)

もちろん、これは合法的な構文ではありません。

編集:明らかに私の質問は明確ではありませんでした。私が欲しいのは、このようにできることです:

CREATE TABLE my_table(text nvarchar(50))
INSERT INTO my_table VALUES('Message 2')
INSERT INTO my_table VALUES('Message 3')

DECLARE @errors xml
SET @errors = '<errors><error>Message 1</error></errors>'

SET @errors.modify('INSERT EVERYTHING FROM my_table MAGIC STATEMENT')

そして、このコードを実行した後、@errorsには

<errors>
  <error>Message 1</error>
  <error>Message 2</error>
  <error>Message 3</error>
</errors>
4

3 に答える 3

2

これはもっと簡単ではありませんか?

set ErrorXML=(SELECT * from #MyTable FOR XML AUTO)
于 2010-06-27T07:59:42.707 に答える
1

最後の更新:

OK、質問がより明確になったので、彼が解決策です-うまくいけば!!

DECLARE @errors xml
SET @errors = '<errors><error>Message 1</error></errors>'

DECLARE @newErrors XML 

SELECT @newErrors = (SELECT text AS 'error'
FROM dbo.my_table 
FOR XML PATH(''), ELEMENTS)

SELECT @errors, @newErrors

SET @errors.modify('insert sql:variable("@newErrors") as last into (/errors)[1]')

SELECT @errors

これは私に与えます

先頭の @errors

<errors><error>Message 1</error></errors>   

「魔法の」SELECTの後の@newError:

<error>Message 2</error><error>Message 3</error>

UPDATE後の@エラー:

<errors>
    <error>Message 1</error>
    <error>Message 2</error>
    <error>Message 3</error>
</errors>

それはあなたが探しているものですか?? :-)


(古い回答-OPが探していたものではありません.....)

SQL XQueryの関数を確認する必要があります。.nodes()これは、XPath 式に基づいて、XML 変数を XML ノードのリストに分割します (これは、XML 内のノードの列挙がある可能性が高いポイントを参照します)。同じ構造)、「仮想」テーブルと列名を与えます。

その「Table.Column」要素に基づいて、その XML ノードから単一の値 (属性またはサブ要素のいずれか) を選択でき、これらを「アトミック」値 (INT、VARCHAR(x) など、必要なものは何でも) として取得できます。 . これらの値をテーブルに挿入できます。

INSERT dbo.YourTable(col1, col2, col3, ..., colN)
  SELECT
     Error.Column.value('@attr1[1]', 'varchar(20)'),
     Error.Column.value('subitem[1]', 'int'),
     .....
     Error.Column.value('subitemN[1]', 'DateTime')
  FROM
     @xmldata.nodes('/error') AS Error(Column)

更新:では、反対のことをしたい - リレーショナル データを XML に変換する - それはさらに簡単です :-)

DECLARE @NewXmlContent XML

SELECT @NewXmlContent = 
       (SELECT
          col1 as '@ID',
          col2 as 'SomeElement',
          .....
          colN as 'LastElement'
       FROM 
          dbo.YourTable
       WHERE
           ....
       FOR XML PATH('element'), ROOT('root')
       )

UPDATE YourOtherTable
SET XmlField.modify('insert sql:variable("@NewXmlContent") 
                     as last into (/XPath)[1]')
WHERE (some condition)

これにより、@NewXmlContent に次のようなものが表示されます。

<root>
   <element ID="(value of col1)">
      <SomeElement>(value of col2)</SomeElement>
      .....
      <LastElement>(value of colN)</LastElement>
   </element>
</root>

呼び出しを伴う UPDATE ステートメントは、.modify()そのコンテンツをデータベース内の既存の XML フィールドに実際に挿入します。これは、既存の XML 列に XML コンテンツを取得する唯一の方法です。挿入される XML フラグメント内の別の XML 列を直接参照する方法はありません。

新しい "FOR XML PATH" 構文は非常に強力で柔軟性があり、ほぼ何でも実行できます。

もちろん、それを XML 変数に簡単に格納することもできます。

マルク

于 2009-11-20T12:50:25.970 に答える
0

マークの回答に基づいて、SQL Server 2005 で機能するソリューションを次に示します。

CREATE TABLE #my_table(text nvarchar(50))
INSERT INTO #my_table VALUES('Message 2')
INSERT INTO #my_table VALUES('Message 3')

DECLARE @errors xml
SET @errors = '<errors><error>Message 1</error></errors>'

SELECT @errors = CAST(@errors AS nvarchar(max)) + '<new>' + (SELECT text AS 'error' FROM #my_table FOR XML PATH(''), ELEMENTS) + '</new>'

SET @errors = CAST(@errors AS nvarchar(max)) + '<new>' + @newErrors + '</new>'
SET @errors.modify('insert (/new/*) as last into (/errors)[1]')
SET @errors.modify('delete (/new)')

SELECT @errors

DROP TABLE #my_table

戻ります

<errors>
  <error>Message 1</error>
  <error>Message 2</error>
  <error>Message 3</error>
</errors>
于 2010-01-06T15:20:13.617 に答える