特定のサーバー上の一連のデータベースのログイン権限を表示するSSRSレポートに取り組んでいます。
サーバー、ログイン、データベースはすべてパラメーターです。 NULLはそれらすべてを示します(ログインおよびDBS)サーバー-1つのみ-指定する必要があります。
プロシージャは、COMMA DELIMITED STRINGとしてプロシージャに渡す複数のパラメータを受け入れます。ここが間違いだと思います。
レポートには、提供されたログインのリストと提供されたDBのリストのパーミッションのみをリストする必要があります。
これは、ストアドプロシージャに渡されるパラメーターを収集するレポートの画像です。
以下に示すように、ストアドプロシージャはレポート内から実行されます。さらに、ストアドプロシージャの出力を含む画像の下にも実行されます。
exec bsp_GetServerDBRoles
@SERVER=N'my server\instance',
@LOGINS=NULL,
@DBS='master'
これで、以下に、私のストアドプロシージャのコードが表示されます。
PRINT 'THE SERVER IS ' + @@SERVERNAME
--select db_name()
PRINT 'THE DATABASE IS ' + db_NAME()
PRINT ''
GO
USE [Monitoring]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
BEGIN TRY
PRINT @@SERVERNAME
PRINT DB_NAME()
PRINT 'PROCEDURE bsp_GetServerDBRoles'
DROP PROCEDURE bsp_GetServerDBRoles
print 'dropped PROCEDURE bsp_GetServerDBRoles'
END TRY
BEGIN CATCH
END CATCH
GO
CREATE PROCEDURE bsp_GetServerDBRoles
@SERVER NVARCHAR(128),
@LOGINS NVARCHAR(MAX)=NULL,
@DBS NVARCHAR(MAX)=NULL
WITH EXECUTE AS OWNER, ENCRYPTION
AS
/*
=======================================================================
Script : bsp_GetServerDBRoles
Author : Marcelo Miorelli
Date : 5-May-2015
Desc : this procedure shows the database names on a specific server
it needs @SERVER to be a linked server with enabled data access in the current server.
Usage :
exec bsp_GetServerDBRoles @SERVER=N'my server/instance',@LOGINS=N'my login',@DBS=N'AppFabric'
go
exec bsp_GetServerDBRoles 'my server'
SELECT * FROM OPENQUERY([my server\instsqlweb1],'SET FMTONLY OFF;SET NOCOUNT ON; exec sp_GetServerDBRoles ''UKStock,US15AUTPProduct''')
--================================================================
-- using a temp table to store the results
--================================================================
BEGIN TRY
DROP TABLE #Radhe
END TRY
BEGIN CATCH
END CATCH
CREATE TABLE #Radhe(
[DB_Name] [nvarchar](128) NULL
)
--==================================================================================
--this way it does not work -- An INSERT EXEC statement cannot be nested.
-- see the links below
--INSERT INTO #Radhe
--exec sp_GetServerLogins
--==================================================================================
-- and if you get the error below:
-- Server 'SQLSALON1\STOCKALLOCATION' is not configured for DATA ACCESS
--select @@servername
-- get this done first:
--EXEC sp_serveroption @server = @@servername
-- ,@optname = 'data access'
-- ,@optvalue = 'TRUE'
declare @sql nvarchar(max)
select @sql = 'SELECT
[DB_Name]
FROM OPENQUERY(' + quotename(@@servername) + ',' + '''' + 'SET FMTONLY OFF; exec monitoring.dbo.bsp_GetServerDBRoles ' + '''' + '''' + 'SQLREPLON1\REP' + '''' + '''' + '''' + ')'
--print ( @sql)
INSERT INTO #Radhe
exec ( @sql)
select
[DB_Name]
from #Radhe
Links :
=======================================================================
Vritasura talking to Indra:
SB 6.12.14: Since everything is dependent on the supreme will of the Personality of Godhead,
one should be equipoised in fame and defamation,
victory and defeat, life and death.
In their effects,
represented as happiness and distress,
one should maintain oneself in equilibrium, without anxiety.
SB 6.12.15: One who knows that the three qualities — goodness, passion and ignorance —
are not qualities of the soul but qualities of material nature,
and who knows that the pure soul is simply an observer of the actions and reactions of these qualities,
should be understood to be a liberated person.
He is not bound by these qualities.
=======================================================================
History
Date Action User Desc
-----------------------------------------------------------------------
05-May-2015 created Marcelo Miorelli
=======================================================================
*/
SET NOCOUNT ON
SET XACT_ABORT ON
SET DEADLOCK_PRIORITY NORMAL;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @I INT
,@Z INT
,@LOGIN nvarchar(128)
DECLARE @sql NVARCHAR(MAX)
DECLARE @log NVARCHAR(MAX)
,@vCrlf CHAR(2);
SELECT @log = ''
,@vCrlf = CHAR(13)+CHAR(10);
SELECT @SERVER = COALESCE(UPPER(LTRIM(RTRIM(@SERVER))),@@SERVERNAME)
IF NOT EXISTS(
SELECT *
FROM SYS.SERVERS
WHERE NAME = @SERVER
AND PROVIDER = 'SQLNCLI'
AND is_data_access_enabled = 1
) BEGIN
SELECT @SQL = 'The server called %s cound not be found, or does not have data access enabled.' + @vCrlf + @vCrlf +
'bsp_GetServerDBRoles usage:' + @vCrlf +
'bsp_GetServerDBRoles @Server sysname' + @vCrlf +
'Example:' + @vCrlf +
'bsp_GetServerDBRoles ''sqlreplon1\rep''' + @vCrlf
RAISERROR(@SQL ,16,1,@SERVER)
RETURN (-1)
END
BEGIN TRY
--==================================================================================
-- and if you get the error below:
-- Server 'SQLSALON1\STOCKALLOCATION' is not configured for DATA ACCESS
-- get this done first:
--EXEC sp_serveroption @server = @SERVER
-- ,@optname = 'data access'
-- ,@optvalue = 'TRUE'
--DECLARE @Radhe TABLE (
-- db nvarchar(128) NULL,
-- login_ nvarchar(128) NULL,
-- role_ nvarchar(128) NULL,
-- Obj nvarchar(517) NULL,
-- Permission nvarchar(128) NULL,
-- script nvarchar(588) NULL
--)
SELECT @DBS = CASE WHEN LEN(LTRIM(RTRIM(@DBS))) < 1 THEN NULL ELSE LTRIM(RTRIM(@DBS)) END
SELECT @LOGINS = CASE WHEN LEN(LTRIM(RTRIM(@LOGINS))) < 1 THEN NULL ELSE LTRIM(RTRIM(@LOGINS)) END
select @sql = 'SELECT
[name]
,[Type_Desc]
,[The_Server_Roles]
,[List_of_Groups_Login_belong_to]
,[dbname]
,[modify_date]
,[Permissions_user]
FROM OPENQUERY(' + quotename(@SERVER) + ',' + '''' + 'SET FMTONLY OFF;SET NOCOUNT ON; exec sp_GetServerDBRoles ' +
CASE WHEN @DBS IS NULL THEN 'NULL'
ELSE '''' + '''' + @DBS + '''' + ''''
END + ',' +
CASE WHEN @LOGINS IS NULL THEN 'NULL'
ELSE '''' + '''' + @LOGINS + '''' + ''''
END + '''' + ')'
print @sql
exec ( @sql)
RETURN (0)
END TRY
BEGIN CATCH
PRINT '--EXCEPTION WAS CAUGHT--' + CHAR(13) +
'THE ERROR NUMBER:' + COALESCE(CAST ( ERROR_NUMBER() AS VARCHAR), 'NO INFO') + CHAR(13)
PRINT 'SEVERITY: ' + COALESCE(CAST ( ERROR_SEVERITY() AS VARCHAR), 'NO INFO') + CHAR(13) +
'STATE: ' + COALESCE(CAST ( ERROR_STATE() AS VARCHAR), 'NO INFO') + CHAR(13)
PRINT 'PROCEDURE: ' + COALESCE(CAST ( COALESCE(ERROR_PROCEDURE(),'NO INFO') AS VARCHAR), 'NO INFO') + CHAR(13) +
'LINE NUMBER: ' + COALESCE(CAST ( ERROR_LINE() AS VARCHAR), 'NO INFO') + CHAR(13)
PRINT 'ERROR MESSAGE: '
PRINT CAST ( COALESCE(ERROR_MESSAGE(),'NO INFO') AS NTEXT)
RETURN (-1)
END CATCH;
------------------------------------
GO
------------------------------------
print 'created PROCEDURE bsp_GetServerDBRoles'
GO
-- exec sys.sp_MS_marksystemobject 'bsp_GetServerDBRoles'
--GO
問題は
以下に示すようにストアドプロシージャを呼び出すと、例外が発生します。
exec bsp_GetServerDBRoles
@SERVER=N'my server\instance'
the list of my logins'
例外は次のとおりです。
--EXCEPTION WAS CAUGHT--
THE ERROR NUMBER:7357
SEVERITY: 16
STATE: 2
PROCEDURE: NO INFO
LINE NUMBER: 1
ERROR MESSAGE:
Cannot process the object "SET FMTONLY OFF;SET NOCOUNT ON; exec sp_GetServerDBRoles 'the list of my logins ...
レポートが呼び出すプロシージャは、SQLMON1と呼ばれる監視サーバーにあります。そこから、LINKED SERVERSを介して、パラメーターとして渡されたサーバーに移動し、必要なデータを返すローカルストアドプロシージャがあります。
質問:
カンマ区切りの文字列の代わりにテーブルタイプを使用することは、このための良い解決策でしょうか?
監視するサーバーごとにこのテーブルタイプを作成する必要があります。
これは客観的な質問ではないことを理解しています。
ここでの問題は、SSRSパラメーターが値を返す方法です。
たとえば、bsp_GetServerDBRoles
ストアドプロシージャを実行しようとしたとき(デモでは@Loginパラメータが長すぎるため、スキップしました):
exec bsp_GetServerDBRoles
@SERVER=N'my server'
,@DBS=N'UK15AUTMProduct,UK15SUMMProduct,UK15SUMSProduct,UK15WINPProduct'
@DBSで予期される値の形式は次のとおりです。
'UK15AUTMProduct','UK15SUMMProduct','UK15SUMSProduct','UK15WINPProduct'
しかし、ssrsパラメータ@DBSは以下の形式で複数の値を返すため、クエリは失敗します。
UK15AUTMProduct,UK15SUMMProduct,UK15SUMSProduct,UK15WINPProduct
これを解決するには、ストアドプロシージャで新しい変数を宣言するには、@DBSNEW
を想定し、その値を次のように設定します。
SET @DBSNEW = REPLACE(@DBS,',',''',''')
これにより、以下に示すように、SSRS @DBSパラメータから返される値が変わります。
UK15AUTMProduct','UK15SUMMProduct','UK15SUMSProduct','UK15WINPProduct
これで、引用符が最初と最後に欠けているため、動的選択クエリのwhere句で@DBSNEW変数を('''+@DBSNEW+''')
として使用します。お役に立てれば。