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
我的设置 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