SQL 服务器在 SQL 函数中执行 (sp_executesql ) 命令
SQL Server execute (sp_executesql ) command in SQL function
我在 SQL 服务器中创建了一个函数来执行动态 SQL 查询和 return 一个值。在 SQL 查询中调用函数时出现错误:
Only functions and some extended stored procedures can be executed from within a function
函数:(return 与@ModuleName 关联的用户数)
DECLARE @Query NVARCHAR(MAX)
DECLARE @Result int
DECLARE @UsersUsingModule AS NVARCHAR(99)
SET @Query = 'SELECT @UsersUsingModule = Count(UR.UserId) '+
'FROM '+@UserDBName+'.[dbo].[aspnet_UsersInRoles] AS UR '+
'INNER JOIN '+@UserDBName+'.[dbo].[aspnet_Roles] AS R ON UR.RoleId = R.RoleId '+
'INNER JOIN '+@UserDBName+'.[dbo].[aspnet_Users] AS U ON UR.UserId = U.UserId '+
'WHERE LOWER(RoleName) IN ( '+
'SELECT LOWER([Role]) '+
'FROM ADMIN_ROLEACCESS '+
'WHERE LOWER(ModuleName) = LOWER(@ModuleName) '+
')'
EXEC sp_executesql @Query, N'@ModuleName nvarchar(max), @UsersUsingModule INT OUTPUT', @ModuleName, @UsersUsingModule OUTPUT
SELECT @Result = CAST(@UsersUsingModule as INT)
RETURN @Result
查询:
SELECT
M.ID as [ModuleID], M.ModuleName, CC.UserLicenses,
dbo.fncRolesWithModule(M.ModuleName) AS [Roles],
[dbo].[fncUsersUsingModule](M.ModuleName, 'USERS_Demo2016')
FROM
ADMIN_ClientsContracts as CC
INNER JOIN
ADMIN_Modules as M ON CC.ModuleID = M.ID
WHERE
CC.Isactive = 1
如果有更好的方法请多多指教!
根据定义,FUNCTION 永远不允许更改 table 内容。这里它只是一个 SELECT,我明白,但恕我直言,函数并不是为此而设计的。 存储过程 就是为实现这一目的而设计的。
如果您仍然想继续做您打算做的事情,那么您可能必须使用 this 网站中提到的一些技巧,在更长的时间 [=26] =].
您可以关注this问题进行类似的讨论!
希望对您有所帮助!
函数用于计算,类似于 SELECT
查询。您不能在函数内执行存储过程。在这种情况下,您正试图在函数内部使用过程 sp_executesql
,这导致了这个问题。
如果您想执行相同的步骤,而不是函数,您可以使用如下过程。
CREATE PROCEDURE dbo.GetUserModule
@UserDBName NVARCHAR(50),
@ModuleName NVARCHAR(150)
AS
BEGIN
DECLARE @Query NVARCHAR(MAX)
DECLARE @Result int
DECLARE @UsersUsingModule AS NVARCHAR(99)
SET @Query = 'SELECT @UsersUsingModule = Count(UR.UserId) '+
'FROM '+@UserDBName+'.[dbo].[aspnet_UsersInRoles] AS UR '+
'INNER JOIN '+@UserDBName+'.[dbo].[aspnet_Roles] AS R ON UR.RoleId = R.RoleId '+
'INNER JOIN '+@UserDBName+'.[dbo].[aspnet_Users] AS U ON UR.UserId = U.UserId '+
'WHERE LOWER(RoleName) IN ( '+
'SELECT LOWER([Role]) '+
'FROM ADMIN_ROLEACCESS '+
'WHERE LOWER(ModuleName) = LOWER(@ModuleName) '+
')'
EXEC sp_executesql @Query, N'@ModuleName nvarchar(max), @UsersUsingModule INT OUTPUT'
, @ModuleName
, @UsersUsingModule OUTPUT
SELECT @Result = CAST(@UsersUsingModule as INT)
RETURN @Result
END
我在 SQL 服务器中创建了一个函数来执行动态 SQL 查询和 return 一个值。在 SQL 查询中调用函数时出现错误:
Only functions and some extended stored procedures can be executed from within a function
函数:(return 与@ModuleName 关联的用户数)
DECLARE @Query NVARCHAR(MAX)
DECLARE @Result int
DECLARE @UsersUsingModule AS NVARCHAR(99)
SET @Query = 'SELECT @UsersUsingModule = Count(UR.UserId) '+
'FROM '+@UserDBName+'.[dbo].[aspnet_UsersInRoles] AS UR '+
'INNER JOIN '+@UserDBName+'.[dbo].[aspnet_Roles] AS R ON UR.RoleId = R.RoleId '+
'INNER JOIN '+@UserDBName+'.[dbo].[aspnet_Users] AS U ON UR.UserId = U.UserId '+
'WHERE LOWER(RoleName) IN ( '+
'SELECT LOWER([Role]) '+
'FROM ADMIN_ROLEACCESS '+
'WHERE LOWER(ModuleName) = LOWER(@ModuleName) '+
')'
EXEC sp_executesql @Query, N'@ModuleName nvarchar(max), @UsersUsingModule INT OUTPUT', @ModuleName, @UsersUsingModule OUTPUT
SELECT @Result = CAST(@UsersUsingModule as INT)
RETURN @Result
查询:
SELECT
M.ID as [ModuleID], M.ModuleName, CC.UserLicenses,
dbo.fncRolesWithModule(M.ModuleName) AS [Roles],
[dbo].[fncUsersUsingModule](M.ModuleName, 'USERS_Demo2016')
FROM
ADMIN_ClientsContracts as CC
INNER JOIN
ADMIN_Modules as M ON CC.ModuleID = M.ID
WHERE
CC.Isactive = 1
如果有更好的方法请多多指教!
根据定义,FUNCTION 永远不允许更改 table 内容。这里它只是一个 SELECT,我明白,但恕我直言,函数并不是为此而设计的。 存储过程 就是为实现这一目的而设计的。
如果您仍然想继续做您打算做的事情,那么您可能必须使用 this 网站中提到的一些技巧,在更长的时间 [=26] =].
您可以关注this问题进行类似的讨论!
希望对您有所帮助!
函数用于计算,类似于 SELECT
查询。您不能在函数内执行存储过程。在这种情况下,您正试图在函数内部使用过程 sp_executesql
,这导致了这个问题。
如果您想执行相同的步骤,而不是函数,您可以使用如下过程。
CREATE PROCEDURE dbo.GetUserModule
@UserDBName NVARCHAR(50),
@ModuleName NVARCHAR(150)
AS
BEGIN
DECLARE @Query NVARCHAR(MAX)
DECLARE @Result int
DECLARE @UsersUsingModule AS NVARCHAR(99)
SET @Query = 'SELECT @UsersUsingModule = Count(UR.UserId) '+
'FROM '+@UserDBName+'.[dbo].[aspnet_UsersInRoles] AS UR '+
'INNER JOIN '+@UserDBName+'.[dbo].[aspnet_Roles] AS R ON UR.RoleId = R.RoleId '+
'INNER JOIN '+@UserDBName+'.[dbo].[aspnet_Users] AS U ON UR.UserId = U.UserId '+
'WHERE LOWER(RoleName) IN ( '+
'SELECT LOWER([Role]) '+
'FROM ADMIN_ROLEACCESS '+
'WHERE LOWER(ModuleName) = LOWER(@ModuleName) '+
')'
EXEC sp_executesql @Query, N'@ModuleName nvarchar(max), @UsersUsingModule INT OUTPUT'
, @ModuleName
, @UsersUsingModule OUTPUT
SELECT @Result = CAST(@UsersUsingModule as INT)
RETURN @Result
END