Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 从SQL Server Service broker使用SSIDB实现调用SSIS_Sql Server_Ssis_Service Broker - Fatal编程技术网

Sql server 从SQL Server Service broker使用SSIDB实现调用SSIS

Sql server 从SQL Server Service broker使用SSIDB实现调用SSIS,sql-server,ssis,service-broker,Sql Server,Ssis,Service Broker,要求是通过SSI调用web服务,并从SQL Server service Broker激活的存储过程调用SSI 以下是我目前正在做的事情: 排队 我的存储过程: ALTER PROCEDURE [schema].[usp_ProccessingQueueActivation] WITH EXECUTE AS CALLER AS BEGIN SET NOCOUNT ON; <snip declaration> BEGIN BEGIN TRAN

要求是通过SSI调用web服务,并从SQL Server service Broker激活的存储过程调用SSI

以下是我目前正在做的事情:

排队

我的存储过程:

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
ALTER过程[schema]。[usp\u过程队列激活]
以EXECUTE作为调用方
作为
开始
不计数;
开始
开始交易;
等待
(
接收顶部(1)
@会话句柄=会话句柄,
@MessageBody=CAST(消息体为XML),
@MessageTypeName=消息类型名称
来自[schema]。[ProcessingQueue]
),超时5000;
EXEC dbo.RunSSIS
声明@ReplyMessageBody XML=@MessageBody;
会话发送@ConversationHandle消息类型[TYPE](@ReplyMessageBody);
结束
提交事务;
结束
结束
下面是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
ALTER过程[dbo].[RunSSIS]
作为
开始
声明@exec_id BIGINT
EXEC[SSISDB].[catalog].[create_execution]
@包名称=N“”,
@文件夹名称=N“”,
@项目名称=N“”,
@use32bitruntime=FALSE,
@reference_id=NULL,
@execution\u id=@exec\u id输出
EXEC[SSIDB].[catalog].[set\u execution\u parameter\u value]
@行政长官,
@对象类型=30,
@参数_name=N“”,
@参数值=
选择@exec\u id
EXEC[SSISDB].[catalog].[start\u execution]@EXEC\u id
结束
现在,这将在事件查看器中引发以下异常,因为在SSIDB环境中无法识别Sql service broker激活安全上下文

激活的进程 正在上运行的“[schema].[usp_ProcessingQueueActivation]” 队列“”将输出 以下内容:'无法还原当前安全上下文。请 切换到调用“执行为”的原始数据库,然后重试 再说一遍。”

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

  • 所以我关注这个链接 并创建了一个具有自签名证书的用户(认为 是没有权限的用户)。但它返回了同样的错误, 深入挖掘,我发现,[internal].[prepare\u execution]在 SSIDB在第36行中有“REVERT”语句,该语句将错误作为 它一点也不喜欢模仿

    • 我尝试将RunSSIS存储过程移动到SSIDB,并尝试从激活存储过程调用它,但由于SSIDB不允许任何具有SQL Server身份验证的用户,它需要具有Windows身份验证,并且由证书创建的用户显然不具有Windows凭据,因此被击落
我的问题是

  • 我走的路对吗?我当然不认为同时使用SQL server的两个组件会有那么困难
  • 如果不是正确的方法,那么从ServiceBroker调用服务的最佳方法是什么?我已经看到了SQLServerServiceBroker的“外部激活”,但还没有探究它。但我会坚持使用服务器环境内部的可扩展组件,不喜欢在prod环境中安装不同的组件(这对于个人支持来说总是一种开销,因为还有一点可能会失败)

我正在使用Windows auth,并且我的凭据具有系统管理员权限。

我认为您可以去掉“以调用方身份执行”,所有内容(进程以及最终被调用的包)都将在Service Broker的安全上下文下运行。只要该上下文具有执行您想执行的操作的权限,您就可以了


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

这有一种紧密耦合的代码味道,我的第一反应是将队列、存放proc的DB和SSIS执行分离到PowerShell脚本中。让脚本从service broker获取消息,然后在不同的连接上调用SSISDB,而无需在存储过程中包装
[catalog].[create\u execution]
[catalog].[set\u execution\u parameter\u value]
。您仍然可以直接从代理运行此脚本


如果其中一个组件移动到不同的服务器,如果某个组件在dev/QA中的名称不同,或者技术发生变化(例如Azure ServiceBus而不是Broker),这种方法在安全上下文方面为您提供了最大的灵活性。您还可以通过日志记录/监视获得创造性。

这看起来更适合于查看代码签名是否有效?现在回答这个问题有点晚了,实际上我们已经放弃了从Sql service broker调用SSIS->webservice的整个过程,而是使用Sql CLR路由。为了保护呼叫安全,我们禁用匿名呼叫,并强制Windows登录,因为它是intranet站点,而且我们希望所有呼叫该站点的人都应该登录,这是可行的。但我仍然认为这是微软错失的一次机会,它实际上是从数据库创建了一个真正的基于推送事件的系统。为了记录,如果没有EXECUTE AS子句,跨数据库模块签名将无法从service broker激活过程中工作,而EXECUTE AS调用者将无法工作,它必须是某个特定的用户
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