从SQL Server Service Broker通过SSISDB实现调用SSIS

问题描述 投票:10回答:3

要求是通过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) 

我的存储过程:

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

现在这是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

现在,这将在事件查看器中引发以下异常,因为在SSISDB环境中无法识别Sql Service Broker激活安全上下文。

已激活的过程正在运行的[[schema]。[usp_ProccessingQueueActivation]'队列''输出以下内容:“当前的安全上下文无法还原。请切换到调用“ Execute As”的原始数据库,然后尝试再来一次。'

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

  • 所以我点击了此链接http://www.databasejournal.com/features/mssql/article.php/3800181/Security-Context-of-Service-Broker-Internal-Activation.htm并创建了一个具有自签名证书的用户(认为是没有权限的用户)。但是它返回了同样的错误,进行更深入的研究后,我发现其中的[内部]。[准备执行]SSISDB在第36行有“ REVERT”语句,该语句将错误抛出为它根本不喜欢模仿。

    • 我试图将RunSSIS存储过程移至SSISDB并尝试从激活存储过程中调用它,它被击倒为SSISDB,它不允许任何具有SQL Server身份验证的用户,它需要具有Windows身份验证并创建了用户通过证书显然没有Windows凭据。

我的问题是

  • 我在正确的路径上吗?我当然不认为同时使用SQL Server的2个组件会那么困难。
  • 如果使用的方法不正确,从服务经纪人处调用服务的最佳方法是什么?我已经看到SQL Server Service Broker的“外部激活”,但尚未进行探索。但是我会尽量坚持那些驻留在服务器环境中并且可扩展的东西,并且不喜欢在产品环境中安装不同组件的想法(这对于个人支持来说总是一项开销,因为还有一点可以失败)

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

sql-server ssis service-broker
3个回答
0
投票

[我认为您可以取出“ WITH EXECUTE AS CALLER”,所有内容(proc,然后最终被调用的程序包)将在Service Broker的安全上下文下运行。只要该上下文有权执行您想做的事情,就可以了。

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


0
投票

这具有紧密耦合的代码味道,我的第一个直觉是将队列,容纳proc的数据库以及SSIS执行分离为PowerShell脚本。让脚本从服务代理获取消息,然后在不同的连接上调用SSISDB,而无需将[catalog].[create_execution][catalog].[set_execution_parameter_value]包装在存储的proc中。您仍然可以直接从代理运行此脚本。

如果组件之一移至另一台服务器,或者在dev / QA中使用不同的名称,或者技术发生了变化(例如,Azure ServiceBus而不是Broker),此方法将为您提供最大的安全性灵活性。您还可以通过日志记录/监视来发挥创意。


-1
投票

[如果可以,请分享您用于SQLCLR的脚本提示?那会很有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.