SQL Server إدراج بيانات من الجدول إلى متغير XML
-
21-09-2019 - |
سؤال
كيف يمكنني إدراج مجموعة كاملة من الصفوف في متغير 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.
مارك