我在一个只执行作业的表上有一个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);他们能够在表格中插入记录,但触发器不会触发。
我是SQL Server新手,我的印象是用户不需要提升权限来触发触发器(我认为这是一个很大的好处!)。这是触发级别或作业级别的权限问题吗?我该怎么做才能解决这个限制?
答案 0 :(得分:2)
触发器将在调用者的上下文中执行,调用者可能有也可能没有访问msdb的权限。这似乎是你的问题。有几种方法可以使用Execute As扩展这些权限;它们在link
中非常详细在触发器中使用模拟:
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
另一种方法(取决于代理作业执行的操作)将利用Service Broker队列来处理存储过程激活。您的用户上下文将简单地调用Send On队列,而在异步过程中,SvcBroker将激活在较高提升用户的上下文中执行的存储过程。我会选择这个解决方案而不是依赖于调用代理作业的触发器。
我想测试对Service Broker的调用,所以我编写了这个简单的测试示例。我只是发送一封电子邮件,而不是调用SSIS包,但它与您的情况非常相似。注意我在脚本的顶部使用SET TRUSTWORTHY ON。请阅读有关此设置的含义。
要运行此示例,您需要替换下面的电子邮件个人资料信息,<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;
*/
答案 1 :(得分:1)
这将是工作级别的权限。您可以将这些用户分配给MSDB中的SQLAgentReaderRole,以便能够启动作业,考虑到它们将被添加到拥有该作业的组中。如果他们不属于拥有这份工作的团队,那就更难了。