有没有办法让函数像对象一样工作?
例如:我有一个类似xml的函数:
CREATE FUNCTION dbo.CompanyXml(@id int) RETURNS XML
AS
BEGIN
RETURN (SELECT id AS [@id], name AS [@name] FROM Companies WHERE id = @id
FOR XML PATH('CompanyType'),TYPE)
END
当我使用该功能时:
SELECT dbo.CompanyXml(1) AS Supplier,
dbo.CompanyXml(2) AS Client
FOR XML PATH('Document'), TYPE
我明白了:
<Document>
<Supplier>
<CompanyType id="1" name="Company 1" />
</Supplier>
<Client>
<CompanyType id="2" name="Company 2" />
</Client>
</Document>
但我需要:
<Document>
<Supplier id="1" name="Company 1" />
<Client id="2" name="Company 2" />
</Document>
有没有办法实现这个目标?
[更新]我的解决方案
(受@Shnugo启发)
我使用了表值函数FOR XML AUTO
CREATE FUNCTION dbo.CompanyTbl(@id int) RETURNS TABLE
AS SELECT id, name FROM Companies WHERE id = @id
像这样使用
SELECT (SELECT * FROM dbo.CompanyTbl(1) AS Supplier FOR XML AUTO, TYPE),
(SELECT * FROM dbo.CompanyTbl(2) AS Client FOR XML AUTO, TYPE)
FOR XML PATH('Document'), TYPE
答案 0 :(得分:1)
别名AS Supplier
或AS Client
是结果集中特定列的标题。您呼叫的功能不知道(并且无法知道),其结果将显示为供应商或客户......
使用FOR XML PATH()
元素的名称必须是文字。
有三种方法,我选择最后一种方法:
您可以使用像Kannan Kandasamys建议的修改功能,但每个角色需要一个部分,您必须将“type”作为参数提交。更多角色需要修改功能。部署的数据库可能很难......
您可以在字符串级别创建xml(类似'<' + @element + id="' + ...
),然后使用CAST(... AS XML)
。在这种情况下,请注意如何处理特殊字符!
(我的选择):为每个文档角色引入一个单独的函数。新角色是新功能,在大多数情况下更容易
对于Nr 3,您的代码看起来像
SELECT dbo.SupplierXml(1) AS [*],
dbo.ClientXml(2) AS [*]
FOR XML PATH('Document'), TYPE;
FOR XML AUTO
试试这个:
CREATE DATABASE TestDB;
GO
USE TestDB;
GO
CREATE TABLE TestTable(id INT,SomeOther VARCHAR(100));
INSERT INTO TestTable VALUES(1,'Some 1'),(2,'Some 2');
SELECT * FROM TestTable FOR XML AUTO;
- 结果:您看,表名是元素的名称:
<TestTable id="1" SomeOther="Some 1" />
<TestTable id="2" SomeOther="Some 2" />
- 很好,您可以使用表别名强制使用此名称:
SELECT * FROM TestTable AS OtherName FOR XML AUTO;
- 返回
<OtherName id="1" SomeOther="Some 1" />
<OtherName id="2" SomeOther="Some 2" />
GO
USE master;
GO
DROP DATABASE TestDB;
现在不好的是,那个 - 再次 - 别名必须是文字,不能作为参数传入。它不是可内联的,但您可以执行类似
的操作DECLARE @cmd VARCHAR(1000)='SELECT * FROM YourTable AS ' + @alias + ' FOR XML AUTO';
EXEC (@cmd);
当谈到动态设置列名(同样适用于元素名称)时,你必须使用一些丑陋的技巧......
答案 1 :(得分:0)
您可以更改以下功能:
CREATE FUNCTION dbo.CompanyXml1(@id int, @type varchar(15)) RETURNS XML
AS
BEGIN
if @type = 'Supplier'
begin
return(
SELECT id AS [@id], name AS [@name] FROM Companies WHERE id = @id
FOR XML PATH('Supplier'),TYPE )
end
else
begin
return(
SELECT id AS [@id], name AS [@name] FROM Companies WHERE id = @id
FOR XML PATH('Client'),TYPE
)
end
return(null);
END
您的查询如下:
SELECT dbo.CompanyXml1(1, 'Supplier'),
dbo.CompanyXml1(2, 'Client')
FOR XML PATH('Document'), TYPE
输出......:
<Document>
<Supplier id="1" name="Company 1" />
<Client id="2" name="Company 2" />
</Document>