1

単にジョブを実行するテーブルにINSERTトリガーがあります。

例:

CREATE TABLE test
(
    RunDate smalldatetime
)

CREATE TRIGGER StartJob ON test 
AFTER INSERT 
AS
    EXEC msdb.dbo.sp_start_job 'TestJob'

このテーブルにレコードを挿入すると、問題なくジョブが実行されます。ただし、私よりも権限が低い人が数人います(データベースのdb_datareader / db_datawriterのみ)。テーブルにレコードを挿入することはできますが、トリガーは起動しません。

私はSQLServerの初心者であり、トリガーを起動するためにユーザーが昇格されたアクセス許可を必要としないという印象を受けました(これは大きな利点の1つだと思いました!)。これはトリガーレベルでの許可の問題ですか、それともジョブレベルでの許可の問題ですか?この制限を回避するにはどうすればよいですか?

4

2 に答える 2

2

トリガーは、msdbにアクセスするためのアクセス許可を持っている場合と持っていない場合がある呼び出し元のコンテキストで実行されます。それがあなたの問題のようです。[名前を付けて実行]を使用してこれらの権限を拡張する方法はいくつかあります。それらはこのリンクで非常に詳細に説明されています

トリガー内で偽装を使用します。

CREATE TRIGGER StartJob ON test  
with execute as owner
AFTER INSERT 
AS
EXEC msdb.dbo.sp_start_job 'TestJob'

そして、データベースを信頼できるものに設定します(または上記のリンクへのサインインについて読んでください):

alter database TestDB set trustworthy on

(エージェントジョブが実行する操作に応じて)別の方法は、ServiceBrokerキューを利用してストアドプロシージャのアクティブ化を処理することです。ユーザーのコンテキストは単にSendOnthe queueを呼び出しますが、非同期プロセスでは、SvcBrokerは上位のユーザーのコンテキストで実行されるストアドプロシージャをアクティブにします。エージェントジョブを呼び出すトリガーに依存するのではなく、このソリューションを選択します。

Service Brokerへの呼び出しをテストしたかったので、この簡単なテスト例を作成しました。SSISパッケージを呼び出す代わりに、私は単に電子メールを送信しますが、それはあなたの状況に非常に似ています。スクリプトの上部でSETTRUSTWORTHYONを使用していることに注意してください。この設定の意味についてお読みください。

このサンプルを実行するには<your_email_address_here>、以下の電子メールプロファイル情報などに置き換える必要があります。

use Master;
go
if exists(select * from sys.databases where name = 'TestDB')
    drop database TestDB;
create database TestDB;
go
alter database TestDB set ENABLE_BROKER; 
go
alter database TestDB set TRUSTWORTHY ON;

use TestDB;
go

------------------------------------------------------------------------------------
-- create procedure that will be called by svc broker
------------------------------------------------------------------------------------
create procedure dbo.usp_SSISCaller
as
set nocount on;
declare @dlgid uniqueidentifier;
begin try

    -- * figure out how to start SSIS package from here

    -- for now, just send an email to illustrate the async callback 
        ;receive top(1) 
                @dlgid = conversation_handle
        from SSISCallerQueue;

        if @@rowcount = 0
        begin
            return;
        end

        end conversation @dlgid;

    exec msdb.dbo.sp_send_dbmail 
        @profile_name           = '<your_profile_here>',
        @importance             = 'NORMAL',
        @sensitivity            = 'NORMAL',
        @recipients             = '<your_email_address_here>', 
        @copy_recipients        = '',
        @blind_copy_recipients  = '', 
        @subject                = 'test from ssis caller',
        @body                   = 'testing',
        @body_format            = 'TEXT'; 

    return 0;

end try
begin catch
    declare @msg varchar(max);
    select @msg = error_message();
    raiserror(@msg, 16, 1);

    return -1;
end catch;
go

------------------------------------------------------------------------------------
-- setup svcbroker objects
------------------------------------------------------------------------------------
create contract [//SSISCallerContract]
    ([http://schemas.microsoft.com/SQL/ServiceBroker/DialogTimer] sent by initiator)

create queue SSISCallerQueue 
    with status = on, 
    activation (    
        procedure_name = usp_SSISCaller,
        max_queue_readers = 1,
        execute as 'dbo' );

create service [//SSISCallerService] 
    authorization dbo
    on queue SSISCallerQueue ([//SSISCallerContract]);
go

return;


-- usage 
/*

-- put a row into the queue to trigger the call to usp_SSISCaller

begin transaction;

    declare @dlgId uniqueidentifier;

    begin dialog conversation @dlgId
                from service   [//SSISCallerService]
                to service      '//SSISCallerService', 
                                'CURRENT DATABASE'
                on contract     [//SSISCallerContract]
                with encryption = off;

    begin conversation timer (@dlgId)
            TIMEOUT = 5; -- seconds

commit transaction;
*/
于 2011-04-05T16:58:29.070 に答える
1

ジョブ レベルでのアクセス許可になります。これらのユーザーがジョブを所有するグループに追加されることを考慮して、MSDB で SQLAgentReaderRole を割り当てて、ジョブを開始できるようにすることができます。彼らが仕事を所有するグループに属していない場合、それはより困難になります。

于 2011-04-05T17:01:48.180 に答える