从SQL Server服务代理调用SSIS与SSISDB实现

Suk*_*nta 10 sql-server ssis service-broker

要求是通过SSIS调用Web服务并从SQL Server Service Broker激活的存储过程调用SSIS.

这是我目前正在做的事情:

队列

   CREATE QUEUE [schema].[ProccessingQueue] WITH STATUS = ON , RETENTION = OFF , ACTIVATION (  STATUS = ON , PROCEDURE_NAME = [schema].[usp_ProccessingQueueActivation] , MAX_QUEUE_READERS = 10 , EXECUTE AS N'dbo'  ), POISON_MESSAGE_HANDLING (STATUS = ON) 
Run Code Online (Sandbox Code Playgroud)

我的存储过程:

ALTER PROCEDURE [schema].[usp_ProccessingQueueActivation]
WITH EXECUTE AS CALLER
AS

BEGIN
    SET NOCOUNT ON;

    <snip declaration>
    BEGIN
        BEGIN TRANSACTION;

            WAITFOR
            (
                RECEIVE TOP (1)
                    @ConversationHandle = conversation_handle,
                    @MessageBody = CAST(message_body AS XML),
                    @MessageTypeName = message_type_name
                FROM [schema].[ProccessingQueue]
            ), TIMEOUT 5000;

            <snip awasome stuff>
                EXEC dbo.RunSSIS <param>

                DECLARE @ReplyMessageBody XML = @MessageBody;
                SEND ON CONVERSATION @ConversationHandle MESSAGE TYPE [type] (@ReplyMessageBody);
            END

            <handle error>

        COMMIT TRANSACTION;
    END
END
Run Code Online (Sandbox Code Playgroud)

现在这是RunSSIS存储过程的样子

ALTER PROCEDURE [dbo].[RunSSIS]
      <params>
AS
BEGIN
       DECLARE @exec_id BIGINT

       EXEC [SSISDB].[catalog].[create_execution] 
    @package_name=N'<SSIS_package>', 
    @folder_name=N'<folder>', 
    @project_name=N'<projectName>',
    @use32bitruntime=FALSE, 
    @reference_id=NULL,             
    @execution_id=@exec_id OUTPUT   

       EXEC [SSISDB].[catalog].[set_execution_parameter_value] 
       @exec_id, 
       @object_type=30, 
       @parameter_name=N'<param_Name>', 
       @parameter_value=<param>

       SELECT @exec_id

       EXEC [SSISDB].[catalog].[start_execution] @exec_id
END
Run Code Online (Sandbox Code Playgroud)

现在,这将在事件查看器中抛出以下异常,因为在SSISDB环境中无法识别Sql服务代理激活安全性上下文.

激活的proc'[schema].[usp_ProccessingQueueActivation]'在队列上运行''输出以下内容:'当前的安全上下文无法恢复.请切换到调用"执行为"的原始数据库,然后再次尝试.

为了解决这个问题,我尝试了以下方法

  • 所以我按照这个链接 http://www.databasejournal.com/features/mssql/article.php/3800181/Security-Context-of-Service-Broker-Internal-Activation.htm 创建了一个带有自签名证书的用户(认为是没有许可的用户).但它正在返回同样的错误,深入挖掘我发现SSISDB 中的[internal].[prepare_execution]在第36行中有"REVERT"语句抛出错误,因为它根本不喜欢模拟.

    • 我试图将RunSSIS存储过程移动到SSISDB并尝试从激活存储过程调用它,它被击落为SSISDB它不允许任何用户使用SQL Server auth,它需要有一个Windows身份验证和用户创建的证书显然没有Windows凭证.

我的问题是

  • 我在正确的道路上吗?我当然不希望一起使用SQL服务器的2个组件会那么困难.
  • 如果没有正确的方法,从服务代理调用服务的最佳方法是什么?我见过SQL Server服务代理的"外部激活"但尚未探索过.但我会尝试坚持服务器环境和可扩展的东西,并且不喜欢在prod环境中安装不同组件的想法(它总是支持个人的开销,因为还有一点可以失败)

我正在使用Windows身份验证,我的凭据具有sys_Admin访问权限.

btb*_*rry 0

我认为您可以取出“WITH EXECUTE AS CALLER”,所有内容(过程以及最终被调用的包)都将在 Service Broker 的安全上下文下运行。只要该上下文有权执行您想做的事情,就应该没问题。

我没有以这种方式使用 Service Broker,但我对 SQL 代理触发的作业做了同样的事情。只要代理的安全上下文具有 procs/packages 中所需的权限,一切就可以正常运行。我们的服务使用网络帐户,因此服务器之间也可以正常工作。