如何在标量值函数中创建一个循环来一般返回键值对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>
答案 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;
由于命令与以前相同,结果也是如此......