【问题标题】:Form xml element from SQL Server tableSQL Server 表中的表单 xml 元素
【发布时间】:2017-04-15 08:57:29
【问题描述】:

我想将 sql 表记录转换为以下 xml 格式。能否请您在里面提出您的建议。

SQL Server 表:

id  name
-------------
1   Arun
2   Raghavan

我想在 SQL 查询中像下面的格式一样从上表中形成 xml 元素

<row>
    <Field Name="Customer.id" Value="id">
    <Field Name="Customer.name" Value="arun">
</row>

【问题讨论】:

    标签: sql sql-server xml


    【解决方案1】:

    这就是我的想法。

    这是一个动态反透视,然后将其转换回统一的 XML 对象。

    我添加了 Cross Apply C 来保存表名,但这可以是一个变量。

    Declare @YourTable table (id int,name varchar(50))
    Insert into @YourTable values
    (1,'Arun'),
    (2,'Raghavan')
    
    Select D.*
     From  @YourTable A
     Cross Apply (Select XMLData=cast((Select A.* for XML Raw) as xml) ) B
     Cross Apply (Select TableName='Customer') C
     Cross Apply (
                    Select row = (
                                    Select [@Name]   = C.TableName+'.'+attr.value('local-name(.)','varchar(100)')
                                          ,[@Value]  = attr.value('.','varchar(max)') 
                                     From  B.XMLData.nodes('/row') as A(r)
                                     Cross Apply A.r.nodes('./@*') AS B(attr)
                                     For XML Path('Field'),Type
                                  )
                ) D
     For XML Path(''),Type
    

    退货

    <row>
      <Field Name="Customer.id" Value="1" />
      <Field Name="Customer.name" Value="Arun" />
    </row>
    <row>
      <Field Name="Customer.id" Value="2" />
      <Field Name="Customer.name" Value="Raghavan" />
    </row>
    

    【讨论】:

    • 太好了,我更新了我的答案指向FOR XML AUTO... 这种方法是一个很好的解决方案,但相当黑客:-D
    • @Shnugo 被称为更糟......今天早上:)
    • 嗨@John,我刚刚放了另一个答案。想想,你会喜欢的:-D
    • @Shnugo 我毫不怀疑。当我回到办公室时,我会偷看一眼。
    【解决方案2】:

    我认为你需要类似的东西

    SELECT 'Customer.id' AS [@Name]
          ,id AS [@Value]
    FROM SomeTable
    FOR XML PATH('Field'),ROOT('row');   
    

    如果您确实需要将表名和列名连接起来,就像您的示例中那样,那么就没有简单的。在这种情况下,John Cappelletti's answer 很棒!

    但是请检查这些开箱即用的方法AUTO 将生成表的名称作为元素的名称):

    CREATE TABLE SomeTable (id int,name varchar(50))
    INSERT INTO SomeTable VALUES
     (1,'Arun')
    ,(2,'Raghavan');
    
    SELECT * FROM SomeTable FOR XML AUTO;
    SELECT * FROM SomeTable FOR XML RAW;
    

    --第一个结果

    <SomeTable id="1" name="Arun" />
    <SomeTable id="2" name="Raghavan" />
    

    --第二个结果

    <row id="1" name="Arun" />
    <row id="2" name="Raghavan" />
    

    【讨论】:

    • 我不想提及列名。因为桌子可以根据我的需要而变化。我希望列名和字段值需要在sql查询中自动填写
    【解决方案3】:

    我将此作为第二个答案,因为方法完全不同:

    首先我使用SELECT ... FOR XML AUTO。这将创建简单的标签,其中表的名称是元素的名称,所有字段都作为属性生成。

    从这里我继续FLWOR XQuery。首先我读取所有节点,然后读取节点内的所有属性。这是根据需要的 XML 重新生成的:

    CREATE TABLE SomeTable (id int,name varchar(50))
    INSERT INTO SomeTable VALUES
     (1,'Arun')
    ,(2,'Raghavan');
    

    --查询(您可以放置​​任何表、视图或 TVF 的名称,而不是“SomeTable”)

    SELECT
    (
    SELECT * FROM SomeTable FOR XML AUTO,TYPE  --<-- Here is the simple SELECT
    ).query('
             for $nd in /*
             return <row>
             {
                 for $attr in $nd/@*
                 return <Field Name="{concat(local-name($nd),".",local-name($attr))}" Value="{$attr}"/>
             }
             </row>');
    GO
    --Clean up (careful with real data!)
    --DROP TABLE SomeTable;
    GO
    

    结果

    <row>
      <Field Name="SomeTable.id" Value="1" />
      <Field Name="SomeTable.name" Value="Arun" />
    </row>
    <row>
      <Field Name="SomeTable.id" Value="2" />
      <Field Name="SomeTable.name" Value="Raghavan" />
    </row>
    

    【讨论】:

    • 最令人印象深刻的。以更少的代码和更快的速度满足 OP 的要求……快 23%。还不知道它是如何工作的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多