Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server execute (sp_executesql ) command in SQL function

I created a function in SQL Server to execute a dynamic SQL query and return a value. I'm getting error when calling function in SQL query:

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

Function: (return number of users associated with @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

Query:

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

Advice me if there is any better approach!

like image 491
Sami Avatar asked Sep 01 '16 04:09

Sami


People also ask

Can we use sp_executesql in function?

It appears that you can't. You can execute extended stored procedure inside a function and, even though sp_executesql is an extended stored procedure (despite its name), it still generates the message "only functions and extended stored procedures can be executed within a function".

Can we use dynamic query in function SQL Server?

You can't execute dynamic sql in user defined functions. Only functions and some extended stored procedures can be executed from within a function.

What is EXEC sp_executesql in SQL?

What is the sp_executesql stored procedure? A SQL Server built-in stored procedures used to run one or multiple SQL statements stored within a string. This stored procedure allows executing static or strings built dynamically.


2 Answers

Functions are used for calculations, something like a SELECT query. You can't execute stored procedures inside a function. In this case you are trying to use the procedure sp_executesql inside the function and that is causing this issue.

If you wanted to perform the same steps, instead of functions you can use a procedure like below.

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
like image 175
Unnikrishnan R Avatar answered Sep 20 '22 02:09

Unnikrishnan R


By definition, a FUNCTION is never allowed to ALTER table contents. Here in this it is just a SELECT, I understand but IMHO FUNCTION's aren't designed for that. STORED PROCEDURES are designed to do that trick.

If you still want to proceed with doing what you intend to do, then you might have to use some hacks as mentioned in this site, which aren't advisable at all on a longer run.

You can follow this question for a similar discussion!

Hope this helps!

like image 42
N00b Pr0grammer Avatar answered Sep 20 '22 02:09

N00b Pr0grammer