根据第一个函数参数的值,具有不同列数的TSQL UDF返回表

根据第一个函数参数的值,具有不同列数的TSQL UDF返回表,sql,sql-server,tsql,relational-database,user-defined-functions,Sql,Sql Server,Tsql,Relational Database,User Defined Functions,可能吗?如果没有,还有什么其他选择 到目前为止,我尝试做的一件事是(不起作用;我也知道,如果第一个参数的值小于0或大于4,我会尝试返回一个未初始化的变量,但这大约是我想要得到的): 我可以使用的另一个选项是返回一个带有连接信息的标量值,如下所示(但我更希望得到一个表): 实际上,如果您定义了返回值,您的代码将可以工作: DECLARE @People TABLE ( Lastname VARCHAR(50), FirstName VARCHAR(50), Email VA

可能吗?如果没有,还有什么其他选择

到目前为止,我尝试做的一件事是(不起作用;我也知道,如果第一个参数的值小于0或大于4,我会尝试返回一个未初始化的变量,但这大约是我想要得到的):

我可以使用的另一个选项是返回一个带有连接信息的标量值,如下所示(但我更希望得到一个表):


实际上,如果您定义了返回值,您的代码将可以工作:

DECLARE @People TABLE (
    Lastname VARCHAR(50),
    FirstName VARCHAR(50),
    Email VARCHAR(50),
    Address VARCHAR(50)
) ;

IF @columns = 1 BEGIN
    INSERT INTO @People (LastName)
        SELECT P.LastName
        FROM Person.Person AS P;
END;
ELSE IF @columns = 2 BEGIN
    INSERT INTO @People (LastName, FirstName)
        SELECT P.LastName, P.FirstName
        FROM Person.Person P;
END;
. . . 
RETURN @People
未使用的列将为
NULL
,对于没有赋值的列来说,这是一个非常合理的值

注:

  • 临时表不支持
    @
    。它们以
    #
    开头。在这种情况下,一个表变量就可以了
  • 我不知道在表中声明列的类型时可以使用
    as
    。它用于生成的列
  • 注意表别名

不确定您的用法,但您需要的是存储过程而不是函数。也就是说,根据提供的参数值而变化的结果集模式表明接口有缺陷。@DanGuzman完全同意,听起来像是XY问题。获取特定输出的一些想法:1)JSON并在func之外解析它/2)临时表并删除未使用的列(hackish)3)-不适用于SQL Server
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;
DECLARE @People TABLE (
    Lastname VARCHAR(50),
    FirstName VARCHAR(50),
    Email VARCHAR(50),
    Address VARCHAR(50)
) ;

IF @columns = 1 BEGIN
    INSERT INTO @People (LastName)
        SELECT P.LastName
        FROM Person.Person AS P;
END;
ELSE IF @columns = 2 BEGIN
    INSERT INTO @People (LastName, FirstName)
        SELECT P.LastName, P.FirstName
        FROM Person.Person P;
END;
. . . 
RETURN @People