2011-12-13 29 views
4

基本上我需要从数据库输出单值和多值字段。大多数数据用户不是技术人员,如果他们能够阅读XML并理解它,那将是非常好的。在另一篇文章的帮助下,我几乎找到了所有的方法。用于XML PATH属性的TSQL属性,类型

我遇到的问题是元素名称不能有任何空格。需要包含可能有空格的显示名称。例如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 '值', 'MV测试' 为' @dispName' 引发执行错误 行代码遗漏(空行标签名)不能与属性为中心可用于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') 
+0

如果这仅仅是对非技术人员的可读性,会强调“_”解决问题了吗? –

+0

然后这将是我的工作,建立_。现在,应用程序为没有空格且不会更改的字段构建系统名称,但用户可以分配显示名称并可以更改它。但如果我没有提出更好的解决方案,那仍然是我将使用的解决方案。 – Paparazzi

+0

你可以发布你想要的输出的例子吗? – Bert

回答

12

不知道我理解你想要什么,这是很难做到与你的代码的东西没有你,所以我创建了一个表样本,我相信是做你已经有的东西。

设置表和数据:

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') 
+0

太棒了,谢谢。好的解决方案一个症状是,即使没有值,它也会显示该元素。如果没有值,有没有办法显示(归因)元素? – Paparazzi

+0

@BalamBalam - 把它放在一个子查询中,只选择一个具有常量值的行。更新了答案。 –

+0

完美,再次感谢 – Paparazzi