【发布时间】:2020-03-21 14:28:58
【问题描述】:
有可能吗?如果没有,还有什么其他选择?
到目前为止,我尝试做的其中一件事是(不起作用;我也知道,如果第一个参数的值是 4,我会尝试返回一个未初始化的变量,但是这大约是我的目标):
SET NOCOUNT ON;
USE AdventureWorks2008;
GO
IF OBJECT_ID('dbo.fn_GetPopleInfo') IS NOT NULL
DROP FUNCTION dbo.fn_GetPopleInfo;
GO
CREATE FUNCTION dbo.fn_GetPopleInfo
(@columns INT) RETURNS TABLE
AS
BEGIN
IF (@columns = 1)
CREATE TABLE @People ( LastName AS VARCHAR(50) );
INSERT INTO @People SELECT P.LastName
FROM Person.Person AS P
ELSE IF (@columns = 2)
CREATE TABLE @People ( LastName AS VARCHAR(50), FirstName AS VARCHAR(50) );
INSERT INTO @People SELECT P.LastName, Person.FirstName
FROM Person.Person AS P
ELSE IF (@columns = 3)
CREATE TABLE @People ( LastName AS VARCHAR(50), FirstName AS VARCHAR(50), Email AS VARCHAR(50) );
INSERT INTO @People SELECT P.LastName, P.FirstName, E.EmailAddress
FROM Person.Person AS P
INNER JOIN Person. EmailAddress AS E ON P.BusinessEntityID = E.BusinessEntityID
ELSE IF (@columns = 4)
CREATE TABLE @People ( LastName AS VARCHAR(50), FirstName AS VARCHAR(50), Email AS VARCHAR(50), Address AS VARCHAR(50) );
INSERT INTO @People SELECT P.LastName, P.FirstName, E.EmailAddress, A.AddressLine1
FROM Person.Person AS P
INNER JOIN Person.EmailAddress AS E ON P.BusinessEntityID = E.BusinessEntityID
INNER JOIN Person.Address AS A ON E.AddressID = A.AddressID
RETURN @People
END
我可以使用的另一个选项是返回一个带有串联信息的标量值,如下所示(但我更希望获得一个表):
SET NOCOUNT ON;
USE AdventureWorks2008;
GO
IF OBJECT_ID('dbo.fn_ConcatPeopleData') IS NOT NULL
DROP FUNCTION dbo.fn_ConcatPeopleData;
GO
CREATE FUNCTION dbo.fn_ConcatPeopleData
(@bid AS NCHAR(5), @columns AS INT ) RETURNS NCHAR(1000)
AS
BEGIN
DECLARE @data AS VARCHAR(8000);
SET @data = '';
IF (@columns = 1)
SELECT @data = @data + CAST(LastName AS VARCHAR(100))
FROM Person.Person AS P
WHERE P.BusinessEntityID = @bid;
ELSE IF (@columns = 2)
SELECT @data = @data + CAST(LastName AS VARCHAR(100))+' ' + CAST(FirstName AS VARCHAR(100))
FROM Person.Person AS P
WHERE P.BusinessEntityID = @bid;
ELSE IF (@columns = 3)
SELECT @data = @data + CAST(LastName AS VARCHAR(100))+' ' + CAST(FirstName AS VARCHAR(100))+', ' +
CAST(E.EmailAddress AS VARCHAR(100))
FROM Person.Person AS P
INNER JOIN Person. EmailAddress AS E ON P.BusinessEntityID = E.BusinessEntityID
WHERE P.BusinessEntityID = @bid;
ELSE IF (@columns = 4)
SELECT @data = @data + CAST(LastName AS VARCHAR(100))+' ' + CAST(FirstName AS VARCHAR(100))+', ' +
CAST(E.EmailAddress AS VARCHAR(100))+', ' + CAST(A.AddressLine1 AS VARCHAR(100))+' ' +
CAST(A.City AS VARCHAR(100))+' ' + CAST(A.PostalCode AS VARCHAR(100))
FROM Person.Person AS P
INNER JOIN Person.EmailAddress AS E ON P.BusinessEntityID = E.BusinessEntityID
INNER JOIN Person.BusinessEntityAddress AS BA ON P.BusinessEntityID = BA.BusinessEntityID
INNER JOIN Person.Address AS A ON BA.AddressID = A.AddressID
WHERE P.BusinessEntityID = @bid;
RETURN @data;
END
SELECT BusinessEntityID, dbo.fn_ConcatPeopleData(BusinessEntityID, 3) AS [Person Info]
FROM Person.Person;
【问题讨论】:
-
不确定你的用法,但你需要一个存储过程而不是一个函数。也就是说,依赖于提供的参数值的不同结果集架构表明接口存在缺陷。
-
@DanGuzman 完全同意,听起来像 XY 问题。获得特定输出的几个想法:1)JSON 并在 func/2)临时表和删除未使用的列(hackish)3)Polymorphic functions - 不适用于 SQL Server
标签: sql sql-server tsql relational-database user-defined-functions