创建循环以返回返回key-value-pair-XML-elements一般

时间:2016-07-18 16:34:02

标签: sql-server xml tsql export

如何在标量值函数中创建一个循环来一般返回键值对XML元素?

我的功能目前看起来像这样:

ALTER FUNCTION [dbo].[GetCustomXML]
(
    @Id UNIQUEIDENTIFIER
)
RETURNS XML
AS
BEGIN
  RETURN (
    SELECT (

    SELECT
    --Table A
    (SELECT [DataItemName] = CASE WHEN [TableA].[Address] IS NOT NULL THEN 'Address' END,
            [DataItemValue] = [TableA].[Address]
    FOR XML PATH(''), ROOT('CUSTOM_DATA_ITEM'), TYPE),
    --Table B
    (SELECT [DataItemName] = CASE WHEN [TableB].[Name] IS NOT NULL THEN 'Name' END,
            [DataItemValue] = [TableB].[Name]
    FOR XML PATH(''), ROOT('CUSTOM_DATA_ITEM'), TYPE),
    ....

FROM [TableA] LEFT JOIN 
[TableB] ON [TableA].[ID] = [TableB].[ID]
FOR XML PATH('OTHER'), ROOT('EXTENSION'), TYPE );

END;

正如您所看到的,我必须专门写下每个变量的路径。我想要一个循环,我只需要编写一次输入每个变量的路径。

这是我想要的结果:

<OTHER>
<EXTENSION>
<CUSTOM_DATA_ITEM>
   <DataItemName>Address</DataItemName> (variable name)
   <DataItemValue>12800 Apple Dr. Houston TX, 77483</DataItemValue> (value inside table column)
</CUSTOM_DATA_ITEM>
<CUSTOM_DATA_ITEM>
   <DataItemName>Name</DataItemName>
   <DataItemValue>David</DataItemValue>
</CUSTOM_DATA_ITEM>
</OTHER>
</EXTENSION>

1 个答案:

答案 0 :(得分:0)

从您的问题中,我不明确,我认为您正在寻找通用的方法来实现您的需求。

这是我在上一个问题中告诉你的方法:

测试表

CREATE TABLE Test1(ID INT, TestVarchar VARCHAR(100),TestDate DATE);
INSERT INTO Test1 VALUES
 (1,'Test 1',{d'2016-01-01'})
,(2,'Test 2',{d'2016-02-02'});

从我的功能来看,你需要一行 但是这种方法也适用于许多行

SELECT 'ID' AS [CUSTOM_DATA_ITEM/DataItemName]
      ,ID AS [CUSTOM_DATA_ITEM/DataItemValue]
      ,''
      ,'TestVarchar' AS [CUSTOM_DATA_ITEM/DataItemName]
      ,TestVarchar AS [CUSTOM_DATA_ITEM/DataItemValue]
      ,''
      ,'TestDate' AS [CUSTOM_DATA_ITEM/DataItemName]
      ,TestDate AS [CUSTOM_DATA_ITEM/DataItemValue]
FROM Test1
WHERE ID=2
FOR XML PATH('EXTENSION'),ROOT('OTHER');
GO

结果

<OTHER>
  <EXTENSION>
    <CUSTOM_DATA_ITEM>
      <DataItemName>ID</DataItemName>
      <DataItemValue>2</DataItemValue>
    </CUSTOM_DATA_ITEM>
    <CUSTOM_DATA_ITEM>
      <DataItemName>TestVarchar</DataItemName>
      <DataItemValue>Test 2</DataItemValue>
    </CUSTOM_DATA_ITEM>
    <CUSTOM_DATA_ITEM>
      <DataItemName>TestDate</DataItemName>
      <DataItemValue>2016-02-02</DataItemValue>
    </CUSTOM_DATA_ITEM>
  </EXTENSION>
</OTHER>

现在你要求循环了。我认为 - 你真正想要的 - 是一种不用手动输入所有列名的通用方法。 这是在正常情况下无法实现!!

但是动态创建语句是可能的。一个很大的回退:这肯定 - 不会在标量函数中工作!你必须调用存储过程并使用输出参数来输出结果。

所以:我们需要表格的名称和ID(很可能你也需要ID列变量的名称):

DECLARE @tblNm VARCHAR(100)='Test1';
DECLARE @ID INT=2;

- 现在我们从上面创建语句作为字符串

DECLARE @cmd VARCHAR(MAX)=
(
    SELECT 'SELECT '
    + STUFF(
        (
            SELECT ',''' + COLUMN_NAME + ''' AS  [CUSTOM_DATA_ITEM/DataItemName],'
                 + COLUMN_NAME + ' AS [CUSTOM_DATA_ITEM/DataItemValue],'''''
            FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=@tblNm 
            FOR XML PATH('')
        ),1,1,'')  
    + ' FROM ' + @tblNm + ' WHERE ID=''' + CAST(@ID AS VARCHAR(100)) + ''' FOR XML PATH(''EXTENSION''),ROOT(''OTHER'');'
);

- 并执行它

EXEC (@cmd);
GO

- 清理

DROP TABLE Test1;

由于命令与以前相同,结果也是如此......