2016-09-01 13 views
1

SQL Serverで動的SQLクエリを実行して値を返す関数を作成しました。 (@ModuleNameに関連付けられているユーザーの戻り数):SQL関数のSQL Server execute(sp_executesql)コマンド

のみの機能といくつかの拡張ストアドプロシージャ、関数

関数内から実行することができます。私は、SQLクエリ内の関数を呼び出すときにエラーを取得しています

DECLARE @Query NVARCHAR(MAX) 
DECLARE @Result int 
DECLARE @UsersUsingModule AS NVARCHAR(99) 

SET @Query = 'SELECT @UsersUsingModule = Count(UR.UserId) '+ 
     'FROM  '[email protected]+'.[dbo].[aspnet_UsersInRoles] AS UR '+ 
     'INNER JOIN '[email protected]+'.[dbo].[aspnet_Roles] AS R ON UR.RoleId = R.RoleId '+ 
     'INNER JOIN '[email protected]+'.[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 

より良いアプローチがあれば教えてください!

+0

は」(http://stackoverflow.com/questions/15180561/getting-an-error-when-executing-a-dynamic-sql-within-a-function-sql-serverを見てくださいこの')。役立つかもしれません :) –

答えて

4

FUNCTIONは、決してテーブルの内容を変更することはできません。ここではこれは単なるSELECTですが、IMHO FUNCTIONはそのために設計されていません。 保存された手順はそのトリックを行うように設計されています。

あなたがやろうとしていることをやり続けたい場合は、thisサイトで述べたようにいくつかのハックを使わなければならないかもしれませんが、これは長期的にはお勧めできません。

thisの質問によく似ています!

あなたの意思決定に役立つことを願っています!

3

基本的には、選択クエリのような計算目的で関数が使用されます。関数内のプロシージャは実行できません。この場合、関数内でプロシージャ '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  '[email protected]+'.[dbo].[aspnet_UsersInRoles] AS UR '+ 
     'INNER JOIN '[email protected]+'.[dbo].[aspnet_Roles] AS R ON UR.RoleId = R.RoleId '+ 
     'INNER JOIN '[email protected]+'.[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 
関連する問題