如何查找在 SQL Server 代理作业中手动设置的 SSIS 包项目参数的值?

问题描述 投票:0回答:1

我有一个名为

MyPackage
的包裹。这是项目的一部分
MyProject

它有三个参数:

ParameterA, ParameterB, ParameterC
  • ParameterA
    是通过环境设置的
  • ParameterB
    正在使用
    design_default_value

我可以使用目录视图

object_parameters
environment_variables
找到这些参数的值。

ParameterC
虽然更复杂。

在项目配置中,

ParameterC
的默认值手动设置为“SomeValue”。我也可以通过
object_parameters
找到它。

在运行包的 SQL Server 代理作业中,

ParameterC
的值设置为“其他值”

我的问题是:在哪里可以找到值“Othervalue”?

我已经编写了下面的查询,但它没有给出满足的“其他值”,它给了我执行包的命令。不是为

ParameterC
设置的值,它是 SQL Server 代理作业配置中的“其他值”。

; WITH EnvironmentValues AS 
(
    SELECT 
        er.project_id,
        ev.name AS variable_name,
        CAST(ev.value AS nvarchar(max)) AS environment_value
    FROM 
        SSISDB.catalog.environment_references er
    LEFT JOIN 
        SSISDB.catalog.environment_references er_ref ON er.reference_id = er_ref.reference_id
    LEFT JOIN 
        SSISDB.catalog.environment_variables ev ON er_ref.environment_folder_name = ev.name
),
DesignAndDefaultValues AS 
(
    SELECT 
        op.project_id,
        op.object_name AS package_name,
        op.parameter_name,
        CAST(op.design_default_value AS nvarchar(max)) design_default_value,
        CAST(op.default_value AS nvarchar(max)) default_value,
        op.object_type
    FROM
        SSISDB.catalog.object_parameters op
    LEFT JOIN 
        SSISDB.catalog.projects p ON op.project_id = p.project_id
    WHERE 
        op.parameter_name NOT LIKE 'CM.%' 
        --  AND op.object_type = 20
        AND p.project_id = 27
),
JobStepParameters AS 
(
    -- Assuming that you have a way to map job step parameters manually set in the SQL Agent job
    SELECT 
        js.job_id,
        js.step_id,
        j.name AS job_name,
        j.enabled as job_enabled,
        js.command AS package_command,
        -- Extract the relevant SSIS package and parameter values from the job step command
        -- This part is tricky, as it depends on how the parameters are passed to the SSIS package
        -- Adjust the extraction logic as needed
        -- Example placeholder:
        js.command AS manually_set_value
    FROM
        msdb.dbo.sysjobs j
    LEFT JOIN 
        msdb.dbo.sysjobsteps js ON j.job_id = js.job_id
    WHERE
        js.subsystem = 'SSIS'
)
INSERT INTO @Resultstable
    SELECT DISTINCT
        f.name AS SSIS_Folder,
        p.name AS SSIS_Project,
        d.package_name AS SSIS_Package_Name,
        d.parameter_name AS SSIS_Parameter_Name,
        jp.job_name AS SQL_Agent_Job_Name,
        jp.job_enabled,
        COALESCE(jp.manually_set_value, e.environment_value,
                 d.default_value, d.design_default_value) AS Parameter_Value_Used,
        CASE
            WHEN jp.manually_set_value IS NOT NULL 
                THEN 'Job manually set'
            WHEN e.environment_value IS NOT NULL 
                THEN 'Environment variable'
            WHEN d.default_value IS NOT NULL 
                THEN 'Default value in package'
            ELSE 'Design default value'
        END AS Value_Source
    FROM 
        SSISDB.catalog.folders f
    LEFT JOIN 
        SSISDB.catalog.projects p ON f.folder_id = p.folder_id
    LEFT JOIN 
        DesignAndDefaultValues d ON p.project_id = d.project_id
    LEFT JOIN 
        EnvironmentValues e ON p.project_id = e.project_id
                            AND d.parameter_name = e.variable_name
    LEFT JOIN 
        JobStepParameters jp ON jp.package_command LIKE '%' + d.package_name + '%'
    ORDER BY
        1, 2, 3, 4, 5

编辑:这些值可以在上面提到的 js.command 中找到。

看起来像这样:

/ISSERVER "\"\SSISDB\MyFolder\MyPackage.dtsx\"" /SERVER "\"MyServer\"" /ENVREFERENCE 13 /Par "\"$Project::ParameterC\"";"\"OtherValue\"" /Par "\"$Project::ParameterD\"";"\"ValueforParameterD\"" /Par "\"$ServerOption::LOGGING_LEVEL(Int16)\"";2 /Par "\"$ServerOption::SYNCHRONIZED(Boolean)\"";True /CALLERINFO SQLAGENT /REPORTING E

我需要提取第一个

/Par "\"$Project::
/CALLERINFO
之间的部分。

那么我需要将其分解如下:

/Par "\"$Project::ParameterC\"";"\"OtherValue\"" 
/Par "\"$Project::ParameterD\"";"\"ValueforParameterD\"" 
/Par "\"$ServerOption::LOGGING_LEVEL(Int16)\"";2 
/Par "\"$ServerOption::SYNCHRONIZED(Boolean)\"";True

仅保留包含文本

'/Par "\"$Project:::'
:

的部分
/Par "\"$Project::ParameterC\"";"\"OtherValue\"" 
/Par "\"$Project::ParameterD\"";"\"ValueforParameterD\"" 

进一步分解这些,以便将这些结果作为记录集

parameter  | value
-----------+--------------------
ParameterC | OtherValue
ParameterD | ValueforParameterD

如何从 js.command 中提取参数及其值?

sql-server ssis sql-server-2019 sql-server-agent ssis-2019
1个回答
0
投票

我需要两个函数才能使其正常工作:

CREATE OR ALTER function [ssis].[split_command_text]
(
@command NVARCHAR(MAX)
)

RETURNS @Resultstable TABLE
(   [command] nvarchar(max),
    parameter_name nvarchar(100),
   [value]  nvarchar(max)
)

AS
BEGIN
IF @command like '%/Par "\"$Project::%'
    BEGIN
    ;WITH NumberedParams AS (
        SELECT 
            ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn,
            value AS param_pair
        FROM STRING_SPLIT(REPLACE(@command, '/Par ', '|'), '|')
        WHERE value LIKE '%$Project::%'
    ),
    ExtractedParams AS (
        SELECT 
            rn,
            SUBSTRING(param_pair, 
                CHARINDEX('$Project::', param_pair) + 10,
                CHARINDEX('""', param_pair, CHARINDEX('$Project::', param_pair) + 10) - (CHARINDEX('$Project::', param_pair) + 10)
            ) AS parameter,
            CASE
                WHEN CHARINDEX('";', param_pair) > 0 THEN
                    SUBSTRING(param_pair, 
                        CHARINDEX('";', param_pair) + 2,
                        CASE 
                            WHEN CHARINDEX(' /', param_pair, CHARINDEX('";', param_pair)) > 0 
                            THEN CHARINDEX(' /', param_pair, CHARINDEX('";', param_pair)) - (CHARINDEX('";', param_pair) + 2)
                            ELSE LEN(param_pair) - (CHARINDEX('";', param_pair) + 1)
                        END
                    )
                ELSE NULL
            END AS value
        FROM NumberedParams
    )
    insert into @Resultstable
    SELECT 
        @command as command,
        REPLACE(parameter, '\', '') AS parameter,
        COALESCE(NULLIF(REPLACE(REPLACE(REPLACE(value, '"', ''), '\', ''), ';', ''), ''), 'NULL') AS value
    FROM ExtractedParams
    WHERE parameter NOT LIKE '%ServerOption%'
    ORDER BY rn;
    END
RETURN
END;

create or alter function ssis.get_actual_used_values(
@SSIS_Folder as nvarchar(255) = NULL,
@SSIS_Project as nvarchar(255) = NULL,
@SSIS_Parameter_Name as nvarchar(255) = NULL,
@Environment_name as nvarchar(255) = NULL,
@SQL_Agent_Job_Name as nvarchar(255) = NULL
) 

RETURNS TABLE AS  RETURN

(
WITH EnvironmentValues AS (
    SELECT er.project_id,
        ev.name AS variable_name,
        cast(ev.value as nvarchar(max)) AS environment_value,
        e.name as environment_name,
        e.environment_id,
        er.reference_id,
        er.environment_folder_name
    FROM SSISDB.catalog.environment_variables ev 
    LEFT JOIN SSISDB.catalog.environments e on ev.environment_id = e.environment_id
    LEFT JOIN  SSISDB.catalog.environment_references er on er.environment_name = e.name
    LEFT JOIN SSISDB.catalog.projects pr on er.project_id = pr.project_id
    LEFT JOIN SSISDB.catalog.folders f1 on e.folder_id = f1.folder_id
    LEFT JOIN SSISDB.catalog.folders f2 on pr.folder_id = f2.folder_id

    WHERE 1=1
    AND  f1.name = f2.name
    AND (@Environment_name is null or e.name = @Environment_name)
    AND (@SSIS_Project is null or pr.name = @SSIS_Project)
),
DesignAndDefaultValues AS (
    SELECT distinct op.project_id, 
        p.name collate SQL_Latin1_General_CP1_CI_AS AS SSIS_project_name,
        op.parameter_name collate SQL_Latin1_General_CP1_CI_AS as parameter_name,
        cast(op.design_default_value as nvarchar(max)) collate SQL_Latin1_General_CP1_CI_AS as design_default_value,
        cast(op.default_value as nvarchar(max)) collate SQL_Latin1_General_CP1_CI_AS as default_value
        FROM SSISDB.catalog.object_parameters op
        LEFT JOIN SSISDB.catalog.projects p ON op.project_id = p.project_id
    WHERE op.parameter_name collate SQL_Latin1_General_CP1_CI_AS not like 'CM.%' and op.object_type = 20 --<-- 20 = project[parameter, 30 = package parameter
    AND (@SSIS_Parameter_Name is null or op.parameter_name = @SSIS_Parameter_Name)
    AND (@SSIS_Project is null or p.name = @SSIS_Project)
    --and op.project_id = 231
    --order by 2,3,4,5
),
JobStepParameters AS (
    -- Assuming that you have a way to map job step parameters manually set in the SQL Agent job
    SELECT 
    js.command as package_command
    ,dp.parameter_name
    ,dp.[value] as manually_set_value
    FROM msdb.dbo.sysjobs j
    LEFT JOIN msdb.dbo.sysjobsteps js ON j.job_id = js.job_id
    OUTER APPLY ssis.split_command_text(js.command) as dp
    WHERE js.subsystem = 'SSIS' and js.command = dp.command
    AND (@SSIS_Parameter_Name is null or dp.parameter_name = @SSIS_Parameter_Name)
    AND (@SQL_Agent_Job_Name is null or j.name = @SQL_Agent_Job_Name)
    --order by 1,2,3
)
SELECT distinct f.name AS SSIS_Folder,
    p.name AS SSIS_Project,
    d.parameter_name AS SSIS_Parameter_Name,
    COALESCE(
        jp.manually_set_value,
        d.default_value,
        env_val.environment_value,
        d.design_default_value
    ) AS Actual_Parameter_Value_Used,
    CASE
        WHEN jp.manually_set_value IS NOT NULL THEN 'Value manually set in SQL Agent Job'
        WHEN d.default_value  IS NOT NULL THEN 'Value manually set in project configuration'
        WHEN env_val.environment_value IS NOT NULL THEN 'Takes value from environment' 
        WHEN d.design_default_value  IS NOT NULL THEN  'Parameter not configured so value from package'
        ELSE '<Cannot be determined>'
    END AS why_this_value,
    j.name AS SQL_Agent_Job_Name,
    j.enabled as SQL_Agent_enabled,
--  d.package_name,
    isnull(env_val.environment_folder_name,f.name) + '\' + env_val.environment_name as related_environment,
    js.command
    --, isnull(env_val.environment_folder_name, f.name ) as env_name
    --,p.name as pname
    --,cast(env_val.reference_id as varchar(10)) as envrefer


FROM SSISDB.catalog.folders f
    LEFT JOIN SSISDB.catalog.projects p ON f.folder_id = p.folder_id
    LEFT JOIN DesignAndDefaultValues d ON p.project_id = d.project_id
    LEFT JOIN EnvironmentValues env_val ON p.project_id = env_val.project_id and  d.parameter_name = env_val.variable_name
    LEFT JOIN msdb.dbo.sysjobsteps js   ON  1=1
                                        --AND js.command  collate SQL_Latin1_General_CP1_CI_AS LIKE '%' + isnull(env_val.environment_folder_name, f.name )   + '%' collate SQL_Latin1_General_CP1_CI_AS 
                                        AND js.command  collate SQL_Latin1_General_CP1_CI_AS LIKE '%' + p.name + '%' collate SQL_Latin1_General_CP1_CI_AS 
                                        AND js.command  collate SQL_Latin1_General_CP1_CI_AS LIKE '%/ENVREFERENCE ' + cast(env_val.reference_id as varchar(10))+ '%' collate SQL_Latin1_General_CP1_CI_AS
                                        
    LEFT JOIN msdb.dbo.sysjobs j ON j.job_id = js.job_id
    LEFT JOIN JobStepParameters jp ON   jp.package_command collate SQL_Latin1_General_CP1_CI_AS = js.command collate SQL_Latin1_General_CP1_CI_AS  
                                        and d.parameter_name = jp.parameter_name
                                        and env_val.variable_name collate SQL_Latin1_General_CP1_CI_AS = jp.parameter_name collate SQL_Latin1_General_CP1_CI_AS
WHERE 1=1
and (@SSIS_Folder is null or f.name = @SSIS_Folder)
and (@Environment_name is null or env_val.environment_name = @Environment_name)
and (@SSIS_Parameter_Name is null or d.parameter_name = @SSIS_Parameter_Name)
and (@SSIS_Project is null or p.name = @SSIS_Project)
and (@SQL_Agent_Job_Name is null or j.name = @SQL_Agent_Job_Name)
    
);

打电话

select * from ssis.get_actual_used_values(NULL,NULL,NULL,NULL,NULL) order by 1,2,3,4,5,6,7,8,9

将告诉您您想了解的有关项目参数的所有信息。是的,我知道代码很丑陋,欢迎我来整理并改进它:)

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