Атрибут TSQL FOR XML PATH включен, введите - PullRequest
6 голосов
/ 13 декабря 2011

В основном мне нужно вывести как одно значение, так и поля значения muti из базы данных.Большинство пользователей данных не являются техническими, и было бы неплохо, если бы они могли прочитать XML и разобраться в этом.С помощью другого поста я дошел почти до конца.

Проблема в том, что имя элемента не может содержать пробелов.Необходимо включить отображаемое имя, которое может содержать пробелы.Например, MVtext displayName = "Текст с несколькими значениями".Если правильный ответ - встроенная схема или другой подход, пожалуйста, дайте мне знать.Я не могу публиковать статическую схему, так как приложение может динамически добавлять поля.И поля могут меняться в зависимости от типа отчета.Поля находятся в таблице, и я прочитал эту таблицу, чтобы создать выборку.

Как передать отображаемое имя, в котором могут быть пробелы для элементов?SQL 2008 R2.

   SELECT top 4
     [sv].[sID] AS '@sID'
    ,[sv].[sParID] AS '@sParID' 
    ,[sv].[docID] AS 'docID'
    ,[sv].addDate as 'addDate'
    ,(SELECT [value] AS 'value'
       FROM  [docMVtext] as [mv]
       WHERE [mv].[sID] = [sv].[sID]
         AND [mv].[fieldID] = '113'
       ORDER BY [mv].[value]
       FOR XML PATH (''), type
     ) AS "To"  
    ,(SELECT [value] AS 'value'
       FROM  [docMVtext] as [mv]
       WHERE [mv].[sID] = [sv].[sID]
         AND [mv].[fieldID] = '130'
       ORDER BY [mv].[value]
       FOR XML PATH (''), type
     ) AS "MVtest" 
  FROM  [docSVsys] as [sv]
  WHERE [sv].[sID] >= '57' 
  ORDER BY 
      [sv].[sParID], [sv].[sID]
  FOR XML PATH('Document'), root('Documents')

Производит:

<Documents>
  <Document sID="57" sParID="57">
    <docID>3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA</docID>
    <addDate>2011-10-28T12:26:00</addDate>
    <To>
      <value>Frank Ermis</value>
      <value>Keith Holst</value>
      <value>Mike Grigsby</value>
    </To>
    <MVtest>
      <value>MV test 01</value>
      <value>MV test 02</value>
      <value>MV test 03</value>
      <value>MV test 04</value>
    </MVtest>
  </Document>
  <Document sID="58" sParID="57">
    <docID>3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA.1</docID>
    <addDate>2011-10-28T12:26:00</addDate>
  </Document>
  <Document sID="59" sParID="59">
    <docID>3.818920.KJKP5LYKTNIODOEI4JDOKJ2BXJI5P0BIA</docID>
    <addDate>2011-10-28T12:26:00</addDate>
    <To>
      <value>Vladimir Gorny</value>
    </To>
  </Document>
  <Document sID="60" sParID="59">
    <docID>3.818920.KJKP5LYKTNIODOEI4JDOKJ2BXJI5P0BIA.1</docID>
    <addDate>2011-10-28T12:26:00</addDate>
  </Document>
</Documents>

Я устал

  SELECT  [value] AS 'value', 'MV test' as 'dispName'

Но я получаю

 <MVtest>
  <value>MV test 01</value>
  <dispName>MV test</dispName>
  <value>MV test 02</value>
  <dispName>MV test</dispName>
  <value>MV test 03</value>
  <dispName>MV test</dispName>
  <value>MV test 04</value>
  <dispName>MV test</dispName>
</MVtest>

SELECT [значение] AS 'value', 'MV test' как '@dispName' Выдает ошибку выполнения. Пропуск тега строки (пустое имя тега строки) нельзя использовать с ориентированной на атрибут сериализацией FOR XML

Желаемый вывод:

  <Documents>
  <Document sID="57" sParID="57">
    <docID>3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA</docID>
    <addDate>2011-10-28T12:26:00</addDate>
    <To>
      <value>Frank Ermis</value>
      <value>Keith Holst</value>
      <value>Mike Grigsby</value>
    </To>
    <MVtest dispName="Multi Value Text">
      <value>MV test 01</value>
      <value>MV test 02</value>
      <value>MV test 03</value>
      <value>MV test 04</value>
    </MVtest>
  </Document>
  </Documents>

Решение:

SELECT top 4
     [sv].[sID] AS '@sID'
    ,[sv].[sParID] AS '@sParID'
    ,'SV' as 'docID/@SVMV' 
    ,[sv].[docID] AS 'docID'
    ,'SV' as 'addDate/@SVMV'
    ,[sv].addDate as 'addDate'
    ,'Email To' as 'To/@DisplayName'
    ,'MV' as 'To/@SVMV'
    ,(SELECT [value] AS 'value'
       FROM  [docMVtext] as [mv]
       WHERE [mv].[sID] = [sv].[sID]
         AND [mv].[fieldID] = '113'
       ORDER BY [mv].[value]
       FOR XML PATH (''), type
     ) AS "To"
    ,'Multi Value Text Sample' as 'MVtext130/@DisplayName'
    ,'MV' as 'MVtext130/@SVMV'      
    ,(SELECT  [value] AS 'value' 
       FROM  [docMVtext] as [mv]
       WHERE [mv].[sID] = [sv].[sID]
         AND [mv].[fieldID] = '130'
       ORDER BY [mv].[value]
       FOR XML PATH (''), type
     ) AS "MVtext130" 
  FROM  [docSVsys] as [sv]
  WHERE [sv].[sID] >= '57' 
  ORDER BY [sv].[sParID], [sv].[sID]
  FOR XML PATH('Document'), root('Documents') 

Вывод решения:

<Documents>
  <Document sID="57" sParID="57">
    <docID SVMV="SV">3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA</docID>
    <addDate SVMV="SV">2011-10-28T12:26:00</addDate>
    <To DisplayName="Email To" SVMV="MV">
      <value>Frank Ermis</value>
      <value>Keith Holst</value>
      <value>Mike Grigsby</value>
    </To>
    <MVtext130 DisplayName="Multi Value Text Sample" SVMV="MV">
      <value>MV test 01</value>
      <value>MV test 02</value>
      <value>MV test 03</value>
      <value>MV test 04</value>
    </MVtext130>
  </Document>
  <Document sID="58" sParID="57">
    <docID SVMV="SV">3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA.1</docID>
    <addDate SVMV="SV">2011-10-28T12:26:00</addDate>
    <To DisplayName="Email To" SVMV="MV" />
    <MVtext130 DisplayName="Multi Value Text Sample" SVMV="MV" />
  </Document>
  <Document sID="59" sParID="59">
    <docID SVMV="SV">3.818920.KJKP5LYKTNIODOEI4JDOKJ2BXJI5P0BIA</docID>
    <addDate SVMV="SV">2011-10-28T12:26:00</addDate>
    <To DisplayName="Email To" SVMV="MV">
      <value>Vladimir Gorny</value>
    </To>
    <MVtext130 DisplayName="Multi Value Text Sample" SVMV="MV" />
  </Document>
  <Document sID="60" sParID="59">
    <docID SVMV="SV">3.818920.KJKP5LYKTNIODOEI4JDOKJ2BXJI5P0BIA.1</docID>
    <addDate SVMV="SV">2011-10-28T12:26:00</addDate>
    <To DisplayName="Email To" SVMV="MV" />
    <MVtext130 DisplayName="Multi Value Text Sample" SVMV="MV" />
  </Document>
</Documents>

Это отличное решение моего вопроса.Одним из признаков добавления атрибута является то, что я получаю элемент, даже если есть строки с нулевым значением.В идеале он не будет перечислять элемент, если нет значений.

Пробовал оператор Case, но даже если я установил значение '', он отображает элемент.

    ,[MVtext130/@DisplayName] = 
     Case (select COUNT(*) FROM [docMVtext] 
                  WHERE [docMVtext].[sID] = [sv].[sID]
                  AND [docMVtext].[fieldID] = '130')
       when '0' then ''
       else 'Multi Value Text Sample'
     end 

Обновлено решение не отображать элемент без значений:

    SELECT top 4
     [sv].[sID] AS '@sID'
    ,[sv].[sParID] AS '@sParID'
    ,'SV' as 'docID/@SVMV' 
    ,[sv].[docID] AS 'docID'
    ,'SV' as 'addDate/@SVMV'
    ,[sv].addDate as 'addDate'
    ,(select top(1) 'Email To'
      from [docMVtext] as C
      where C.[sID] = [sv].[sID] and c.fieldID = '113' ) as 'To/@DisplayName'
    ,(select top(1) 'MV'
      from [docMVtext] as C
      where C.[sID] = [sv].[sID] and c.fieldID = '113' ) as 'To/@SVMV'
    --,'Email To' as 'To/@DisplayName'
    --,'MV' as 'To/@SVMV'
    ,(SELECT [value] AS 'value'
       FROM  [docMVtext] as [mv]
       WHERE [mv].[sID] = [sv].[sID]
         AND [mv].[fieldID] = '113'
       ORDER BY [mv].[value]
       FOR XML PATH (''), type
     ) AS "To"
    ,(select top(1) 'Multi Value Text Sample'
      from [docMVtext] as C
      where C.[sID] = [sv].[sID] and c.fieldID = '130' ) as 'MVtext130/@DisplayName'
    ,(select top(1) 'MV'
      from [docMVtext] as C
      where C.[sID] = [sv].[sID] and c.fieldID = '130' ) as 'MVtext130/@SVMV'
    --,'Multi Value Text Sample' as 'MVtext130/@DisplayName'
    --,'MV' as 'MVtext130/@SVMV'    
    ,(SELECT  [value] AS 'value' 
       FROM  [docMVtext] as [mv]
       WHERE [mv].[sID] = [sv].[sID]
         AND [mv].[fieldID] = '130'
       ORDER BY [mv].[value]
       FOR XML PATH (''), type
     ) AS "MVtext130" 
  FROM  [docSVsys] as [sv]
  WHERE [sv].[sID] >= '57' 
  ORDER BY [sv].[sParID], [sv].[sID]
  FOR XML PATH('Document'), root('Documents')

1 Ответ

14 голосов
/ 13 декабря 2011

Не уверен, что я понимаю, что вы хотите, и вам трудно что-то сделать с вашим кодом без ваших таблиц, поэтому я создал пример, который, как мне кажется, делает то, что у вас уже есть.

Таблица настройки и данные:

declare @Main table
(
  MainID int identity,
  Value int
)

declare @Child table
(
  ChildID int identity,
  MainID int,
  Value int
)

insert into @Main values (10),(20),(30)
insert into @Child values (1,100),(2,200),(2,210)

Запрос, который выполняет примерно то же, что и ваш, уже.

select M.MainID as '@MainID',
       M.Value as 'MainValue',
       (select C.Value as ChildValue
        from @Child as C
        where C.MainID = M.MainID
        for xml path(''), type) as Child
from @Main as M
for xml path('Document'), root('Documents')

Результат:

<Documents>
  <Document MainID="1">
    <MainValue>10</MainValue>
    <Child>
      <ChildValue>100</ChildValue>
    </Child>
  </Document>
  <Document MainID="2">
    <MainValue>20</MainValue>
    <Child>
      <ChildValue>200</ChildValue>
      <ChildValue>210</ChildValue>
    </Child>
  </Document>
  <Document MainID="3">
    <MainValue>30</MainValue>
  </Document>
</Documents>

Я полагаю, что ваш ожидаемый результат будет примерно таким с атрибутом отображаемого имени на дочерних узлах.

<Documents>
  <Document MainID="1">
    <MainValue>10</MainValue>
    <Child DisplayName="Child Display Name">
      <ChildValue>100</ChildValue>
    </Child>
  </Document>
  <Document MainID="2">
    <MainValue>20</MainValue>
    <Child DisplayName="Child Display Name">
      <ChildValue>200</ChildValue>
      <ChildValue>210</ChildValue>
    </Child>
  </Document>
  <Document MainID="3">
    <MainValue>30</MainValue>
  </Document>
</Documents>

Чтобы получить, что вы используете этот запрос вместо:

select M.MainID as '@MainID',
       M.Value as 'MainValue',
       (select top(1) 'Child Display Name'
        from @Child as C
        where C.MainID = M.MainID) as 'Child/@DisplayName',
       (select C.Value as ChildValue
        from @Child as C
        where C.MainID = M.MainID
        for xml path(''), type) as Child
from @Main as M
for xml path('Document'), root('Documents')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...