9

短いバージョン:外部データベースへのアクセス権を役割に付与できますか?

長いバージョン:

アプリケーション SQL Server インスタンス ( ) からデータを取得する Crystal を使用してレポートを作成していますdatabase1

アプリケーションがレポートを実行していて、レポート内の接続を上書きしているため、アプリケーション コードにアクセスできません。

電話交換機から情報を収集しているサーバー ( ) に新しい DB を追加しました。database2この情報の一部をアプリケーション データ ( ) に結合したいと考えていますdatabase1

デザイナ内で (SA としてログインして) 実行するとデータとレポートを結合できますが、アプリケーションを介して外部でレポートを実行すると、かなり一般的なエラー (データの取得に失敗しました) で失敗します。

SAとしてアプリケーションにログインしたかのように、新しいDB権限が原因でエラーが発生していると想定しています。エラーは消えます。

アプリケーションには、レポートを実行するユーザー用の特別な DB ロールがあります。テーブル/ビュー/SP をアプリケーション db に追加する場合 ( database1)、このロールに select/execute を付与するだけで、レポートがオブジェクトにアクセスできるようになります。

現在、別のデータベースにオブジェクトがありますが、ロールに簡単にアクセスできません。

database2既存の役割を介して2 番目のデータベース () を参照する方法はありますか?

例えば:

USE [database1]
GRANT EXECUTE ON [database2].[dbo].[CUSTOM_PROCEDURE] TO [applicationrole1] 

OR

USE [database2]
GRANT EXECUTE ON [dbo].[CUSTOM_PROCEDURE] TO [database1].[dbo].[applicationrole1]

理想的には、新しいユーザーが追加/構成されたときにロールがアプリケーションによって定期的に更新されるため、新しいロールを再作成するのではなく、何らかの形でロールにリンクできるようにしたいと考えています。

(これは問題とは関係がないため、Crystal-Reports でタグ付けされていません)

編集:

次のようなことを行う方法はありますか:

INSERT INTO Database2.sys.database_principals
SELECT * FROM Database1.sys.database_principals
WHERE [type] = 'S'

ユーザー (ログインではなく) をコピーしてから、ロール メンバーを追加するには?

4

2 に答える 2

5

おそらく、両方のデータベースにアクセスできるログインを使用しているでしょう (SA の場合など)。適切なロールを作成し、各データベースに権限を付与してから、両方で (使用しているログインにリンクされた) ユーザーを作成し、作成したロールにそれぞれを追加します。

T-SQL は次のようになります。

use master
go
create login testuser with password = 'mypassword123'
go

use test
go

create role reporting
grant select on something to reporting -- grant your permissions here

create user testuser for login testuser
exec sp_addrolemember 'reporting', 'testuser'
go

use test2
go

create role reporting
grant select on something2 to reporting -- grant your permissions here

create user testuser for login testuser
exec sp_addrolemember 'reporting', 'testuser'
go

これで、接続しtestて実行できます

 select * from something
 select * from test2.dbo.something2

もちろん、目的のストアド プロシージャの権限を EXECUTE に変更することもできますが、それについては既に説明済みのようです。

その後は、単純なスクリプトを実行して、ログインとユーザーを作成し、それらをロールに追加するだけです。

declare @sql nvarchar(max), @username nvarchar(50), @password nvarchar(50)

-- ########## SET PARAMETERS HERE
SET @username = N'testguy'
SET @password = N'test123'
-- ########## END SET PARAMETERS

set @sql = N'USE master; CREATE LOGIN [' + @username + N'] WITH PASSWORD = N''' + @password + N'''; USE database1; CREATE USER [' + @username + N'] FOR LOGIN [' + @username + N']; EXEC sp_addrolemember ''reporting'', ''' + @username + N''';  USE database2; CREATE USER [' + @username + N'] FOR LOGIN [' + @username + N']; EXEC sp_addrolemember ''reporting'', ''' + @username + N''';'
exec sp_executesql @sql

ログイン、ユーザー、およびロールの自動同期

このスクリプトは、すべての SQL ログインを検索し (これを自分にとって意味のあるものに変更できます。ウィンドウと SQL アカウント、特定の文字列を含むアカウントなど)、ユーザーが と で作成されているdatabase1ことdatabase2を確認し、両方が に追加されていることを確認します。reporting役割。reportingロールが両方のデータベースで作成されていることを確認する必要がありますが、これを行う必要があるのは 1 回だけです。

その後、手動で、または SQL エージェント ジョブを使用して、このスクリプトを定期的に実行できます。サーバーのログインを作成するだけです。スクリプトが実行されると、残りの処理が実行されます。

declare @login nvarchar(50), @user1 nvarchar(50), @user2 nvarchar(50), @sql nvarchar(max), @rolename nvarchar(50)

SET @rolename = 'reporting'

declare c cursor for 
select sp.name as login, dp1.name as user1, dp2.name as user2 from sys.server_principals as sp
    left outer join database1.sys.database_principals as dp1 on sp.sid = dp1.sid
    left outer join database2.sys.database_principals as dp2 on sp.sid = dp2.sid
where sp.type = 'S' 
    and sp.is_disabled = 0

open c

fetch next from c into @login, @user1, @user2

while @@FETCH_STATUS = 0 begin

    -- create user in db1
    if (@user1 is null) begin
        SET @sql = N'USE database1; CREATE USER [' + @login + N'] FOR LOGIN [' + @login + N'];'
        EXEC sp_executesql @sql
    end

    -- ensure user is member of role in db1
    SET @sql = N'USE database1; EXEC sp_addrolemember '''+ @rolename + ''', ''' + @login + N''';'
    EXEC sp_executesql @sql

     -- create user in db2
    if (@user2 is null) begin
        SET @sql = N'USE database2; CREATE USER [' + @login + N'] FOR LOGIN [' + @login + N'];'
        EXEC sp_executesql @sql
    end

    -- ensure user is member of role in db2
    SET @sql = N'USE database2; EXEC sp_addrolemember '''+ @rolename + ''', ''' + @login + N''';'
    EXEC sp_executesql @sql

    fetch next from c into @login, @user1, @user2
end


close c
deallocate c

不完全な変更をロールオフするためにトランザクションとエラー処理を追加する必要がありますが、それはあなたに任せます。

于 2012-06-18T11:04:34.307 に答える
1

ストアド プロシージャを所有者として実行するように設定します。

http://msdn.microsoft.com/en-us/library/ms188354.aspx

ストアド プロシージャが配置されているデータベースで信頼できる設定を行います。

http://technet.microsoft.com/en-us/library/ms187861.aspx

両方のデータベースで同じ所有者であることを確認してください。

http://msdn.microsoft.com/en-us/library/ms188676(v=sql.105).aspx

ストアド プロシージャに対する実行権限を、プロシージャを持つデータベースの適切なユーザーまたはロールに付与します。

于 2012-06-18T11:23:52.903 に答える