TSQL 函数返回 EXECUTE @sql 的结果

TSQL Function returning results of EXECUTE @sql

我的设置 table 包含各种设置,例如:

|SettingOneID | AltSettingOneID | SettingTwoID | AltSettingTwoID | SettingThreeID | AltSettingThreeID | 
|------------ | --------------- | ------------ | --------------- | -------------- | ----------------- | 
|NULL         | NULL            | 1            | NULL            | 2              | 3                 | 

我正在尝试创建一个函数,它将 return 使用提供的列名和 bool(bit) 的设置来首先检查可选设置或仅使用默认设置, 如果可选设置不可用,它将回退到默认设置

我需要能够动态提供列名。

我正在使用 SQL Server 2016,但需要支持 SQL Server 2012

有效的sql:

    DECLARE @TryOptionalSetting BIT = 1
    DECLARE @DefaultColumnName NVARCHAR(50) = 'SettingOneID';
    DECLARE @OptionalColumnName NVARCHAR(50) = 'AltSettingOneID';
    DECLARE @ID INT;
    DECLARE @settingId INT;
    DECLARE @sql NVARCHAR(4000) = 
            N'DECLARE @ID INT; SELECT @ID =' + @OptionalColumnName + N' FROM [Settings] WHERE [ID] = 1 AND '+CONVERT(NVARCHAR(1), @TryOptionalSetting)+N' = 1;' +
            N'SELECT @ID = COALESCE(@ID,'+@DefaultColumnName+N')  FROM [Settings] WHERE [ID] = '+CONVERT(NVARCHAR(1), @TryOptionalSetting)+N'; SET @out = @ID';
    exec sp_executesql @sql, N'@out INT OUTPUT', @settingId OUTPUT

    SELECT @settingId
    GO

但是,在函数内

CREATE FUNCTION dbo.GetMySetting(
    @DefaultColumnName NVARCHAR(50),
    @OptionalColumnName NVARCHAR(50),
    @TryOptionalSetting BIT
    )
    RETURNS INT
    WITH EXECUTE AS CALLER
    AS
    BEGIN
        DECLARE @settingId INT;
        DECLARE @sql NVARCHAR(4000) = 
                N'DECLARE @ID INT; SELECT @ID =' + @OptionalColumnName + N' FROM [Settings] WHERE [ID] = 1 AND '+CONVERT(NVARCHAR(1), @TryOptionalSetting)+N' = 1;' +
                N'SELECT @ID = COALESCE(@ID,'+@DefaultColumnName+N')  FROM [Settings] WHERE [ID] = '+CONVERT(NVARCHAR(1), @TryOptionalSetting)+N'; SET @out = @ID';
        exec sp_executesql @sql, N'@out INT OUTPUT', @settingId OUTPUT

        RETURN (@settingId);
    END;
GO

它产生以下错误:

Only functions and some extended stored procedures can be executed from within a function"

我尝试使用临时 tables 和 Table-Value-Function,包括删除 sp_executesql,结果如下:

Invalid use of a side-effecting operator 'INSERT EXEC' within a function.

SQL 中的存储过程更易于创建,函数具有更严格的结构并支持更少的子句和功能。

最简单的方法是将函数转换为存储过程。存储过程没有这个限制。

你不能在函数中这样做。如果您想从 SP 获得标量结果,可以使用 SP 的 OUTPUT 参数。

Get scalar value from SELECT statement in stored proc, from within a stored proc