سؤال

كيف يمكنني إدراج مجموعة كاملة من الصفوف في متغير 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>
هل كانت مفيدة؟

المحلول 3

استنادًا إلى إجابة مارك ، إليك حل يعمل مع 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>

نصائح أخرى

أليس هذا أبسط؟

set ErrorXML=(SELECT * from #MyTable FOR XML AUTO)

اخر تحديث:

حسنًا ، الآن بعد أن أصبح السؤال أكثر وضوحًا ، إنه الحل - نأمل !!

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>   

newerror بعد "السحر" حدد:

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

errors بعد التحديث:

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

هو الذي - التي عن ماذا تبحث؟؟ :-)


(الإجابات القديمة - ليس ما كان يبحث عنه OP .....)

تحتاج إلى إلقاء نظرة على .nodes() الوظيفة في SQL Xquery - سيؤدي ذلك إلى تقسيم متغير XML إلى قائمة بعقد XML ، استنادًا إلى تعبير XPath (يشير إلى نقطة ما في XML الخاص بك حيث من المحتمل أن يكون لديك تعداد للعقد من نفس البنية) ، و IT يعطيهم جدول "افتراضي" واسم العمود.

استنادًا إلى عنصر "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>

وبيان التحديث مع .modify() ستقوم CALL فعليًا بإدراج هذا المحتوى في حقل XML موجود في قاعدة البيانات الخاصة بك. هذه هي الطريقة الوحيدة للحصول على محتويات XML في عمود XML موجود - لا توجد طريقة للإشارة مباشرة إلى عمود XML آخر داخل جزء XML يتم إدخاله ....

بناء جملة "for XML Path" الجديد قوي للغاية ومرن ويسمح لك بالقيام بأي شيء تقريبًا.

وبالطبع ، يمكنك بسهولة تخزين ذلك في متغير XML.

مارك

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top