2016-10-13 2 views
3

У меня есть таблица (DAT_Detail) в SQL Server 2008R2 с XML-столбцом. В XML-столбце есть подробная информация для некоторых тестов ... (Я не могу изменить таблицу на другой дизайн, она должна оставаться как XML). Моя таблица имеет 2 столбца: DAT_Detail_ID (уникальный идентификатор) и XMLDetaildata (XML).Просмотреть XML-данные как таблицу

Это скрипт, чтобы добавить мой тест данные:

INSERT INTO DAT_Detail (DAT_Detail_ID, XMLDetaildata) VALUES ('629E4F85-098D-418B-BF2E-63648DCF60ED', '<NewDataSet><DetailTest_A10><TestValue1>1321</TestValue1><TestValue2>142</TestValue2><TestValue3>153</TestValue3><TestValue4>1645</TestValue4><TestValue5>1123</TestValue5><TestValue6>114</TestValue6><TestValue7>1253</TestValue7></DetailTest_A10></NewDataSet>'); 
INSERT INTO DAT_Detail (DAT_Detail_ID, XMLDetaildata) VALUES ('9B30DDAF-0733-4D0D-BCBD-54DA3B56C8F9', '<NewDataSet><DetailTest_A10><TestValue1>2321</TestValue1><TestValue2>242</TestValue2><TestValue3>253</TestValue3><TestValue4>2645</TestValue4><TestValue5>2123</TestValue5><TestValue6>214</TestValue6><TestValue7>2253</TestValue7></DetailTest_A10></NewDataSet>'); 
INSERT INTO DAT_Detail (DAT_Detail_ID, XMLDetaildata) VALUES ('E647B9FB-7B96-440A-ADCB-300F8DEA4BF1', '<NewDataSet><DetailTest_A10><TestValue1>3321</TestValue1><TestValue2>342</TestValue2><TestValue3>353</TestValue3><TestValue4>3645</TestValue4><TestValue5>3123</TestValue5><TestValue6>314</TestValue6><TestValue7>3253</TestValue7></DetailTest_A10></NewDataSet>'); 
INSERT INTO DAT_Detail (DAT_Detail_ID, XMLDetaildata) VALUES ('50041AE4-BE73-4281-A36E-7448F6F35E03', '<NewDataSet><DetailTest_A10><TestValue1>4321</TestValue1><TestValue2>442</TestValue2><TestValue3>453</TestValue3><TestValue4>4645</TestValue4><TestValue5>4123</TestValue5><TestValue6>414</TestValue6><TestValue7>4253</TestValue7></DetailTest_A10></NewDataSet>'); 
INSERT INTO DAT_Detail (DAT_Detail_ID, XMLDetaildata) VALUES ('87AE23BA-41DE-4C1E-BA4E-37E7C3419FE3', '<NewDataSet><DetailTest_A10><TestValue1>5321</TestValue1><TestValue2>542</TestValue2><TestValue3>553</TestValue3><TestValue4>5645</TestValue4><TestValue5>5123</TestValue5><TestValue6>514</TestValue6><TestValue7>5253</TestValue7></DetailTest_A10></NewDataSet>'); 
INSERT INTO DAT_Detail (DAT_Detail_ID, XMLDetaildata) VALUES ('9AAEA106-35C9-40B8-B0D5-7CA7F59E5D90', '<NewDataSet><DetailTest_A10><TestValue1>6321</TestValue1><TestValue2>642</TestValue2><TestValue3>653</TestValue3><TestValue4>6645</TestValue4><TestValue5>6123</TestValue5><TestValue6>614</TestValue6><TestValue7>6253</TestValue7></DetailTest_A10></NewDataSet>'); 

То, что я хочу, чтобы выбрать 2 или более строк и преобразовать XML в таблицу формата для отображения значений в отчете в SQLReportServer ,

У меня есть запрос для перевода XML в таблицу, но я могу использовать только 1 строку для этого. Как только я попытаюсь взять больше строк, только последняя строка переводится в таблицу.

Мой сценарий:

DECLARE @XML AS XML 
DECLARE @hDoc AS INT 

SELECT @XML = XMLDetaildata FROM DAT_Detail WHERE DAT_Detail_ID = '9B30DDAF-0733-4D0D-BCBD-54DA3B56C8F9' 
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML 

SELECT * 
FROM OPENXML(@hDoc, 'NewDataSet/DetailTest_A10') 
WITH 
(
TestValue1 [int] 'TestValue1', 
TestValue2 [int] 'TestValue2', 
TestValue3 [int] 'TestValue3', 
TestValue4 [int] 'TestValue4', 
TestValue5 [int] 'TestValue5', 
TestValue6 [int] 'TestValue6', 
TestValue7 [int] 'TestValue7' 
) 

EXEC sp_xml_removedocument @hDoc 

Что я получаю таблицу:

TestValue1 TestValue2 TestValue3 TestValue4 TestValue5 TestValue6 TestValue7 
2321  242   253   2645  2123  214   2253 

Я попытался изменить мой сценарий:

SELECT @XML = XMLDetaildata FROM DAT_Detail WHERE DAT_Detail_ID IN ('9B30DDAF-0733-4D0D-BCBD-54DA3B56C8F9', '50041AE4-BE73-4281-A36E-7448F6F35E03') 

, чтобы получить это:

TestValue1 TestValue2 TestValue3 TestValue4 TestValue5 TestValue6 TestValue7 
2321  242   253   2645  2123  214   2253  
4321  442   453   4645  4123  414   4253 

но это провалилось ... есть ли у кого-нибудь еще идея, чтобы я оказался в правильном направлении?

+1

Можете ли вы описать не удалось? –

+0

Определенная одна переменная '@ XML' не может содержать 2 значения. Добавьте 'ORDER BY DAT_Detail_ID ASC/DESC', чтобы убедиться, какой из двух вы получите. – Serg

+0

@SeanLange Я потерпел неудачу, так как не смог найти способ переписать запрос, чтобы получить результат, который я хотел ... Но все три следующих ответа отлично работали, я должен был выбрать один. :-) – Scherbe

ответ

1
Select B.* 
From Dat_Detail A 
Cross Apply (
       Select TestValue1 = B.value('TestValue1[1]','int') 
         ,TestValue2 = B.value('TestValue2[1]','int') 
         ,TestValue3 = B.value('TestValue3[1]','int') 
         ,TestValue4 = B.value('TestValue4[1]','int') 
         ,TestValue5 = B.value('TestValue5[1]','int') 
         ,TestValue6 = B.value('TestValue6[1]','int') 
         ,TestValue7 = B.value('TestValue7[1]','int') 
       From XMLDetaildata.nodes('/NewDataSet') AS A(Grp) 
       Cross Apply A.Grp.nodes('DetailTest_A10') AS B(B) 
      ) B 
Where DAT_Detail_ID IN ('9B30DDAF-0733-4D0D-BCBD-54DA3B56C8F9', '50041AE4-BE73-4281-A36E-7448F6F35E03') 

Возвращает

enter image description here

+0

Thx, я принял ваше решение, потому что он работал отлично, и я мог бы применить его к моей реальной таблице (пример был выше). Лучшая часть, я удалил предложение where, и запрос занял только строки, в которых был задан этот конкретный тест.У меня гораздо больше разных тестов, и теперь я пишу для каждого конкретного теста 1, и запрос показывает только затронутые строки. Действительно мило! – Scherbe

1

Вы можете использовать этот вид раствора:

SELECT TestValue1, 
     TestValue2, 
     TestValue3, 
     TestValue4, 
     TestValue5, 
     TestValue6, 
     TestValue7 
FROM (
    SELECT dd.DAT_Detail_ID, 
      CAST(t.c.query('local-name(.)') as nvarchar(max)) as [Columns], 
      t.c.value('.','nvarchar(max)') as [Values] 
    FROM DAT_Detail dd 
    CROSS APPLY XMLDetaildata.nodes('/NewDataSet/DetailTest_A10/*') as t(c) 
    WHERE dd.DAT_Detail_ID IN (
    '9B30DDAF-0733-4D0D-BCBD-54DA3B56C8F9', 
    '50041AE4-BE73-4281-A36E-7448F6F35E03') 
) t 
PIVOT (
    MAX([Values]) FOR [Columns] IN (TestValue1,TestValue2,TestValue3,TestValue4,TestValue5,TestValue6,TestValue7) 
) as pvt 

Выход:

TestValue1 TestValue2 TestValue3 TestValue4 TestValue5 TestValue6 TestValue7 
4321  442   453   4645  4123  414   4253 
2321  242   253   2645  2123  214   2253 

Или:

SELECT t.c.value('(*)[1]','nvarchar(max)') as TestValue1, 
     t.c.value('(*)[2]','nvarchar(max)') as TestValue2, 
     t.c.value('(*)[3]','nvarchar(max)') as TestValue3, 
     t.c.value('(*)[4]','nvarchar(max)') as TestValue4, 
     t.c.value('(*)[5]','nvarchar(max)') as TestValue5, 
     t.c.value('(*)[6]','nvarchar(max)') as TestValue6, 
     t.c.value('(*)[7]','nvarchar(max)') as TestValue7 
FROM DAT_Detail dd 
CROSS APPLY XMLDetaildata.nodes('/NewDataSet/DetailTest_A10') as t(c) 
WHERE dd.DAT_Detail_ID IN (
'9B30DDAF-0733-4D0D-BCBD-54DA3B56C8F9', 
'50041AE4-BE73-4281-A36E-7448F6F35E03') 
+0

Это решение также помогло мне ... спасибо за вашу помощь. – Scherbe

+1

@Scherbe. Если вы ответили вам, правильный способ поблагодарить человека, который ответил, - это отложить ответ (или принять ответ, если это лучший ответ для вас). Подробнее об этом этикете читайте в StackOverflow [здесь] (https://stackoverflow.com/help/someone-answers). –

1

Использование XML-функции вместо

SELECT n.x.value('TestValue1[1]', 'INT') as TestValue1, n.x.value('TestValue2[1]', 'INT') as TestValue2 --, ... 
FROM DAT_Detail 
CROSS APPLY XMLDetaildata.nodes('/NewDataSet/DetailTest_A10') n(x) 
WHERE DAT_Detail_ID IN ('9B30DDAF-0733-4D0D-BCBD-54DA3B56C8F9', '50041AE4-BE73-4281-A36E-7448F6F35E03') 
+0

Это решение также помогло мне ... спасибо за вашу помощь. – Scherbe

Смежные вопросы