使用SQL Server登录调用SSIS包

时间:2018-01-22 17:04:04

标签: sql-server ssis

我尝试使用SQL和SSIS中的组件从.NET应用程序启动ETL过程。除了创建一个调用存储过程的按钮(包括传入参数)之外,我对.NET应用程序没有任何影响。该应用程序需要SQL Server登录才能连接到数据库。

我遇到的问题是我无法使用SQL登录启动SSIS包(需要Windows登录),并且应用程序无法使用Windows登录(需要SQL登录)。我该如何围绕这个圆圈?

更多细节

该应用程序正在管理数十个仓库维度,每个维度都使用自己的ETL流程。代码的设计是将Table_ID传递给存储过程,该过程创建并启动SSIS执行以运行导入。然后,在SQL中完成ETL的其余部分。一个非常简化的动态SQL脚本看起来就像下面那样,动态SQL的输出显示在:

CREATE PROCEDURE [Core].[Execute_Dimension] (@Dimension_Table_ID int) AS

-----------------------------------------
--DECLARE @Dimension_Table_ID INT  = 2001
-----------------------------------------

/************************************************
Declare variables to work with
************************************************/
DECLARE @Dimension_Table_Name   nvarchar(100)
DECLARE @SSIS_Project_Name      nvarchar(100)
DECLARE @sql_import             nvarchar(max) = N''
DECLARE @sql_transform          nvarchar(max) = N''
DECLARE @sql                    nvarchar(max)

SELECT  @Dimension_Table_Name           = [Dimension_Table_Name],
        @SSIS_Project_Name              = [SSIS_Project_Name]
FROM    [Core].[View_Dimension_Table]
WHERE   [Dimension_Table_ID] = @Dimension_Table_ID

/************************************************
Import
************************************************/
SET @sql_import = CONCAT(N'
-- ====================================================================================
-- Description:     Import Process

BEGIN TRY
    -----------------------------------------
    DECLARE @execution_id bigint
    DECLARE @SSISStatus int

    EXEC [SSISDB].[catalog].[create_execution]                  @package_name       = N''',@Dimension_Table_Name,N'_',@Dimension_Table_ID,N'.dtsx'',
                                                                @execution_id       = @execution_id OUTPUT,
                                                                @folder_name        = N''Trinity'',
                                                                @project_name       = N''',@SSIS_Project_Name,N''',
                                                                @use32bitruntime    = ''FALSE'',
                                                                @reference_id       = Null

    EXEC [SSISDB].[catalog].[set_execution_parameter_value]     @execution_id,
                                                                @object_type        = 50,
                                                                @parameter_name     = N''SYNCHRONIZED'',
                                                                @parameter_value    = 1

    EXEC [SSISDB].[catalog].[start_execution]                   @execution_id

    --Execution has failed if SSISDB status <> 7
    SELECT @SSISStatus = [Status] FROM [SSISDB].[catalog].[executions] WHERE [execution_id] = @execution_id

    -----------------------------------------
    IF @SSISStatus = 7
    BEGIN
        PRINT ''Import: Has Succeeded''
    END
    ELSE
    BEGIN
        PRINT ''Import: Has Failed''
    END
END TRY
    BEGIN CATCH
        PRINT ''Import: Has Failed''
    END CATCH
')

/************************************************
Transform
************************************************/
SET @sql_transform = CONCAT(N'
-- ====================================================================================
-- Description:     Transform Process

BEGIN TRY
    -----------------------------------------
    EXEC [Transform].[Proc_',@Dimension_Table_Name,N'_Transform]
    -----------------------------------------
    PRINT ''Transform: Has Succeeded''
END TRY
BEGIN CATCH
    PRINT ''Transform: Has Failed''
END CATCH

')

/************************************************
Package completed
************************************************/

SET @sql = CONCAT(  @sql_import,
                    @sql_transform
                    )

EXEC (@sql)

提供如下输出:

-- ====================================================================================
-- Description:     Import Process

BEGIN TRY
    -----------------------------------------
    DECLARE @execution_id bigint
    DECLARE @SSISStatus int

    EXEC [SSISDB].[catalog].[create_execution]                  @package_name       = N'ActiveDirectoryUser_2001.dtsx',
                                                                @execution_id       = @execution_id OUTPUT,
                                                                @folder_name        = N'Trinity',
                                                                @project_name       = N'DataMart_ICT',
                                                                @use32bitruntime    = 'FALSE',
                                                                @reference_id       = Null

    EXEC [SSISDB].[catalog].[set_execution_parameter_value]     @execution_id,
                                                                @object_type        = 50,
                                                                @parameter_name     = N'SYNCHRONIZED',
                                                                @parameter_value    = 1

    EXEC [SSISDB].[catalog].[start_execution]                   @execution_id

    --Execution has failed if SSISDB status <> 7
    SELECT @SSISStatus = [Status] FROM [SSISDB].[catalog].[executions] WHERE [execution_id] = @execution_id

    -----------------------------------------
    IF @SSISStatus = 7
    BEGIN
        PRINT 'Import: Has Succeeded'
    END
    ELSE
    BEGIN
        PRINT 'Import: Has Failed'
    END
END TRY
    BEGIN CATCH
        PRINT 'Import: Has Failed'
    END CATCH

-- ====================================================================================
-- Description:     Transform Process

BEGIN TRY
    -----------------------------------------
    EXEC [Transform].[Proc_ActiveDirectoryUser_Transform]
    -----------------------------------------
    PRINT 'Transform: Has Succeeded'
END TRY
BEGIN CATCH
    PRINT 'Transform: Has Failed'
END CATCH

2 个答案:

答案 0 :(得分:1)

应该可以根据解释here代表其他用户或组运行脚本。很快解释它必须看起来像这样:

  1. 添加IMPERSONATE grant
  2. 在数据库(创建用户)上映射Windows和SQL服务器登录
  3. 尝试使用EXECUTE作为'windows login here'
  4. 执行您的脚本
  5. 不要忘记致电REVERT以避免任何意外情况和未经授权的访问

答案 1 :(得分:1)

感谢您的回复。但是,在尝试实现它们时,我没有取得任何成功,特别是围绕脚本的SSIS元素。

我运行以下内容......

--[domain/windowsuser] has sysadmin server role, but no explicit user asigned to individual databases

USE [DataMart_ICT]

CREATE USER [domain/windowsuser] FOR LOGIN [domain/windowsuser]
ALTER ROLE [db_owner] ADD MEMBER [domain/windowsuser]

CREATE USER [DBF_App_Admin] FOR LOGIN [DBF_App_Admin]
ALTER ROLE [db_owner] ADD MEMBER [DBF_App_Admin]

GRANT IMPERSONATE ON USER::[domain/windowsuser] TO [DBF_App_Admin]

...尝试运行我之前介绍的代码的这个小节(​​导致问题的位)......

USE [DataMart_ICT]
GO

    EXECUTE AS LOGIN = 'domain/windowsuser'

        -----------------------------------------
        DECLARE @execution_id bigint
        DECLARE @SSISStatus int

        EXEC [SSISDB].[catalog].[create_execution]                  @package_name       = N'ActiveDirectoryUser_2001.dtsx',
                                                                    @execution_id       = @execution_id OUTPUT,
                                                                    @folder_name        = N'Trinity',
                                                                    @project_name       = N'DataMart_ICT',
                                                                    @use32bitruntime    = 'FALSE',
                                                                    @reference_id       = Null

        EXEC [SSISDB].[catalog].[set_execution_parameter_value]     @execution_id,
                                                                    @object_type        = 50,
                                                                    @parameter_name     = N'SYNCHRONIZED',
                                                                    @parameter_value    = 1

        EXEC [SSISDB].[catalog].[start_execution]                   @execution_id

        --Execution has failed if SSISDB status <> 7
        SELECT @SSISStatus = [Status] FROM [SSISDB].[catalog].[executions] WHERE [execution_id] = @execution_id

USE [DataMart_ICT]
GO
REVERT

...并收到以下错误:

The current security context cannot be reverted. Please switch to the original database where 'Execute As' was called and try it again.

问题似乎与EXEC [SSISDB]。[目录]。[start_execution]有关。如果我注释掉这一行就行了。看看这个(MS Built and defined)程序,它已经包含了自己的EXECUTE AS和REVERT,我显然无法改变它。

如果我调用[msdb]。[dbo]。[sp_start_job],我会遇到类似的问题,如果我要调用启动SSIS包的SQL作业,我将需要它。