

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 PostgreSQL 中使用 AWS SCT 扩展包模拟 SQL Server 代理
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent"></a>

SQL Server Agent 是运行 SQL Server 作业的 Microsoft Windows 服务。SQL Server Agent 可以根据计划、为响应特定事件或者按需运行作业。有关 SQL Server Agent 的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/ssms/agent/sql-server-agent?view=sql-server-ver15)。

PostgreSQL 没有 SQL Server Agent 的等效服务。要模拟 SQL Server 代理功能，请 AWS SCT 创建一个扩展包。此扩展包使用 AWS Lambda 和 Amazon CloudWatch。 AWS Lambda 实现用于管理计划和运行作业的接口。亚马逊 CloudWatch 维护计划规则。

AWS Lambda 而且 Amazon CloudWatch 使用 JSON 参数进行交互。此 JSON 参数具有以下结构。

```
{
    "mode": mode,
    "parameters": {
        list of parameters
    },
    "callback": procedure name
}
```

在前面的示例中，*`mode`* 是任务的类型，`list of parameters` 是一组取决于任务类型的参数。此外，`procedure name` 是任务完成后运行的过程的名称。

AWS SCT 使用一个 Lambda 函数来控制和运行作业。该 CloudWatch 规则开始运行作业，并提供启动作业所需的必要信息。当 CloudWatch 规则触发时，它会使用规则中的参数启动 Lambda 函数。

要创建调用过程的简单作业，请使用以下格式。

```
{
    "mode": "run_job",
    "parameters": {
        "vendor": "mysql",
        "cmd": "lambda_db.nightly_job"
    }
}
```

要创建多个步骤作业，请使用以下格式。

```
{
    "mode": "run_job",
    "parameters": {
        "job_name": "Job1",
        "enabled": "true",
        "start_step_id": 1,
        "notify_level_email": [0|1|2|3],
        "notify_email": email,
        "delete_level": [0|1|2|3],
        "job_callback": "ProcCallBackJob(job_name, code, message)",
        "step_callback": "ProcCallBackStep(job_name, step_id, code, message)"
    },
    "steps": [
        {
            "id":1,
            "cmd": "ProcStep1",
            "cmdexec_success_code": 0,
            "on_success_action": [|2|3|4],
            "on_success_step_id": 1,
            "on_fail_action": 0,
            "on_fail_step_id": 0,
            "retry_attempts": number,
            "retry_interval": number
        },
        {
            "id":2,
            "cmd": "ProcStep2",
            "cmdexec_success_code": 0,
            "on_success_action": [1|2|3|4],
            "on_success_step_id": 0,
            "on_fail_action": 0,
            "on_fail_step_id": 0,
            "retry_attempts": number,
            "retry_interval": number
        },
        ...
]
}
```

为了模拟 PostgreSQL 中的 SQL Server 代理行为， AWS SCT 扩展包还创建了以下表格和过程。

## 在 PostgreSQL 中模拟 SQL Server Agent 的表
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.Tables"></a>

为了模拟 SQL Server Agent，扩展包使用以下表：

**sysjobs**  
存储有关作业的信息。

**sysjobsteps**  
存储有关作业步骤的信息。

**sysschedules**  
存储有关作业计划的信息。

**sysjobschedules**  
存储各个作业的计划信息。

**sysjobhistory**  
存储有关计划作业运行的信息。

## 在 PostgreSQL 中模拟 SQL Server Agent 的过程
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.Procedures"></a>

要模拟 SQL Server Agent，扩展包使用以下过程：

**sp\$1add\$1job**  
添加新作业。

**sp\$1add\$1jobstep**  
向作业添加步骤。

**sp\$1add\$1schedule**  
在 Amazon 中创建新的计划规则 CloudWatch。您可以将此计划用于任意数量的作业。

**sp\$1attach\$1schedule**  
设置所选作业的计划。

**sp\$1add\$1jobschedule**  
在 Amazon CloudWatch 中为任务创建计划规则并为该规则设定目标。

**sp\$1update\$1job**  
更新先前创建的作业的属性。

**sp\$1update\$1jobstep**  
更新作业中步骤的属性。

**sp\$1update\$1schedule**  
更新 Amazon 中计划规则的属性 CloudWatch。

**sp\$1update\$1jobschedule**  
更新指定作业计划的属性。

**sp\$1delete\$1job**  
删除作业。

**sp\$1delete\$1jobstep**  
从作业中删除一个作业步骤。

**sp\$1delete\$1schedule**  
删除计划。

**sp\$1delete\$1jobschedule**  
从 Amazon 中删除指定任务的计划规则 CloudWatch。

**sp\$1detach\$1schedule**  
移除计划和作业之间的关联。

**get\$1jobs、update\$1job**  
与之交互的内部程序 AWS Elastic Beanstalk。

**sp\$1verify\$1job\$1date、sp\$1verify\$1job\$1time、sp\$1verify\$1job、sp\$1verify\$1jobstep、sp\$1verify\$1schedule、sp\$1verify\$1job\$1identifiers、sp\$1verify\$1schedule\$1identifiers**  
检查设置的内部过程。

## 在 PostgreSQL 中模拟 SQL Server Agent 的过程的语法
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.Syntax"></a>

扩展包中的 `aws_sqlserver_ext.sp_add_job` 过程模拟 `msdb.dbo.sp_add_job` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-add-job-transact-sql?view=sql-server-ver15)。

```
par_job_name varchar,
par_enabled smallint = 1,
par_description varchar = NULL::character varying,
par_start_step_id integer = 1,
par_category_name varchar = NULL::character varying,
par_category_id integer = NULL::integer,
par_owner_login_name varchar = NULL::character varying,
par_notify_level_eventlog integer = 2,
par_notify_level_email integer = 0,
par_notify_level_netsend integer = 0,
par_notify_level_page integer = 0,
par_notify_email_operator_name varchar = NULL::character varying,
par_notify_netsend_operator_name varchar = NULL::character varying,
par_notify_page_operator_name varchar = NULL::character varying,
par_delete_level integer = 0,
inout par_job_id integer = NULL::integer,
par_originating_server varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_add_jobstep` 过程模拟 `msdb.dbo.sp_add_jobstep` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-add-jobstep-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_step_id integer = NULL::integer,
par_step_name varchar = NULL::character varying,
par_subsystem varchar = 'TSQL'::bpchar,
par_command text = NULL::text,
par_additional_parameters text = NULL::text,
par_cmdexec_success_code integer = 0,
par_on_success_action smallint = 1,
par_on_success_step_id integer = 0,
par_on_fail_action smallint = 2,
par_on_fail_step_id integer = 0,
par_server varchar = NULL::character varying,
par_database_name varchar = NULL::character varying,
par_database_user_name varchar = NULL::character varying,
par_retry_attempts integer = 0,
par_retry_interval integer = 0,
par_os_run_priority integer = 0,
par_output_file_name varchar = NULL::character varying,
par_flags integer = 0,
par_proxy_id integer = NULL::integer,
par_proxy_name varchar = NULL::character varying,
inout par_step_uid char = NULL::bpchar,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_add_schedule` 过程模拟 `msdb.dbo.sp_add_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-add-schedule-transact-sql?view=sql-server-ver15)。

```
par_schedule_name varchar,
par_enabled smallint = 1,
par_freq_type integer = 0,
par_freq_interval integer = 0,
par_freq_subday_type integer = 0,
par_freq_subday_interval integer = 0,
par_freq_relative_interval integer = 0,
par_freq_recurrence_factor integer = 0,
par_active_start_date integer = NULL::integer,
par_active_end_date integer = 99991231,
par_active_start_time integer = 0,
par_active_end_time integer = 235959,
par_owner_login_name varchar = NULL::character varying,
*inout par_schedule_uid char = NULL::bpchar,*
inout par_schedule_id integer = NULL::integer,
par_originating_server varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_attach_schedule` 过程模拟 `msdb.dbo.sp_attach_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-attach-schedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_schedule_id integer = NULL::integer,
par_schedule_name varchar = NULL::character varying,
par_automatic_post smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_add_jobschedule` 过程模拟 `msdb.dbo.sp_add_jobschedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-add-jobschedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_name varchar = NULL::character varying,
par_enabled smallint = 1,
par_freq_type integer = 1,
par_freq_interval integer = 0,
par_freq_subday_type integer = 0,
par_freq_subday_interval integer = 0,
par_freq_relative_interval integer = 0,
par_freq_recurrence_factor integer = 0,
par_active_start_date integer = NULL::integer,
par_active_end_date integer = 99991231,
par_active_start_time integer = 0,
par_active_end_time integer = 235959,
inout par_schedule_id integer = NULL::integer,
par_automatic_post smallint = 1,
inout par_schedule_uid char = NULL::bpchar,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_delete_job` 过程模拟 `msdb.dbo.sp_delete_job` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-delete-job-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_originating_server varchar = NULL::character varying,
par_delete_history smallint = 1,
par_delete_unused_schedule smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_delete_jobstep` 过程模拟 `msdb.dbo.sp_delete_jobstep` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-delete-jobsteplog-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_step_id integer = NULL::integer,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_delete_jobschedule` 过程模拟 `msdb.dbo.sp_delete_jobschedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-delete-jobschedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_name varchar = NULL::character varying,
par_keep_schedule integer = 0,
par_automatic_post smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_delete_schedule` 过程模拟 `msdb.dbo.sp_delete_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-delete-schedule-transact-sql?view=sql-server-ver15)。

```
par_schedule_id integer = NULL::integer,
par_schedule_name varchar = NULL::character varying,
par_force_delete smallint = 0,
par_automatic_post smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_detach_schedule` 过程模拟 `msdb.dbo.sp_detach_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-detach-schedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_schedule_id integer = NULL::integer,
par_schedule_name varchar = NULL::character varying,
par_delete_unused_schedule smallint = 0,
par_automatic_post smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_update_job` 过程模拟 `msdb.dbo.sp_update_job` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-update-job-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer
par_job_name varchar = NULL::character varying
par_new_name varchar = NULL::character varying
par_enabled smallint = NULL::smallint
par_description varchar = NULL::character varying
par_start_step_id integer = NULL::integer
par_category_name varchar = NULL::character varying
par_owner_login_name varchar = NULL::character varying
par_notify_level_eventlog integer = NULL::integer
par_notify_level_email integer = NULL::integer
par_notify_level_netsend integer = NULL::integer
par_notify_level_page integer = NULL::integer
par_notify_email_operator_name varchar = NULL::character varying
par_notify_netsend_operator_name varchar = NULL::character varying
par_notify_page_operator_name varchar = NULL::character varying
par_delete_level integer = NULL::integer
par_automatic_post smallint = 1
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_update_jobschedule` 过程模拟 `msdb.dbo.sp_update_jobschedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-update-jobschedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer
par_job_name varchar = NULL::character varying
par_name varchar = NULL::character varying
par_new_name varchar = NULL::character varying
par_enabled smallint = NULL::smallint
par_freq_type integer = NULL::integer
par_freq_interval integer = NULL::integer
par_freq_subday_type integer = NULL::integer
par_freq_subday_interval integer = NULL::integer
par_freq_relative_interval integer = NULL::integer
par_freq_recurrence_factor integer = NULL::integer
par_active_start_date integer = NULL::integer
par_active_end_date integer = NULL::integer
par_active_start_time integer = NULL::integer
                par_active_end_time integer = NULL::integer
par_automatic_post smallint = 1
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_update_jobstep` 过程模拟 `msdb.dbo.sp_update_jobstep` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-update-jobstep-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer
par_job_name varchar = NULL::character varying
par_step_id integer = NULL::integer
par_step_name varchar = NULL::character varying
par_subsystem varchar = NULL::character varying
par_command text = NULL::text
par_additional_parameters text = NULL::text
par_cmdexec_success_code integer = NULL::integer
par_on_success_action smallint = NULL::smallint
par_on_success_step_id integer = NULL::integer
par_on_fail_action smallint = NULL::smallint
par_on_fail_step_id integer = NULL::integer
par_server varchar = NULL::character varying
par_database_name varchar = NULL::character varying
par_database_user_name varchar = NULL::character varying
par_retry_attempts integer = NULL::integer
par_retry_interval integer = NULL::integer
par_os_run_priority integer = NULL::integer
par_output_file_name varchar = NULL::character varying
par_flags integer = NULL::integer
par_proxy_id integer = NULL::integer
par_proxy_name varchar = NULL::character varying
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_update_schedule` 过程模拟 `msdb.dbo.sp_update_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-update-schedule-transact-sql?view=sql-server-ver15)。

```
par_schedule_id integer = NULL::integer
par_name varchar = NULL::character varying
par_new_name varchar = NULL::character varying
par_enabled smallint = NULL::smallint
par_freq_type integer = NULL::integer
par_freq_interval integer = NULL::integer
par_freq_subday_type integer = NULL::integer
par_freq_subday_interval integer = NULL::integer
par_freq_relative_interval integer = NULL::integer
par_freq_recurrence_factor integer = NULL::integer
par_active_start_date integer = NULL::integer
par_active_end_date integer = NULL::integer
par_active_start_time integer = NULL::integer
par_active_end_time integer = NULL::integer
par_owner_login_name varchar = NULL::character varying
par_automatic_post smallint = 1
out returncode integer
```

## 使用在 PostgreSQL 中模拟 SQL Server Agent 的过程的示例
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.Examples"></a>

要添加新作业，请使用如下所示的 `aws_sqlserver_ext.sp_add_job` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_add_job (
    par_job_name := 'test_job',
    par_enabled := 1::smallint,
    par_start_step_id := 1::integer,
    par_category_name := '[Uncategorized (Local)]',
    par_owner_login_name := 'sa');
```

要添加新的作业步骤，请使用如下所示的 `aws_sqlserver_ext.sp_add_jobstep` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_add_jobstep (
    par_job_name := 'test_job',
    par_step_id := 1::smallint,
    par_step_name := 'test_job_step1',
    par_subsystem := 'TSQL',
    par_command := 'EXECUTE [dbo].[PROC_TEST_JOB_STEP1];',
    par_server := NULL,
    par_database_name := 'GOLD_TEST_SS');
```

要添加简单的计划，请使用如下所示的 `aws_sqlserver_ext.sp_add_schedule` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_add_schedule(
    par_schedule_name := 'RunOnce',
    par_freq_type := 1,
    par_active_start_time := 233000);
```

要为作业设置计划，请使用如下所示的 `aws_sqlserver_ext.sp_attach_schedule` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_attach_schedule (
    par_job_name := 'test_job',
    par_schedule_name := 'NightlyJobs');
```

要为作业创建计划，请使用如下所示的 `aws_sqlserver_ext.sp_add_jobschedule` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_add_jobschedule (
    par_job_name := 'test_job2',
    par_name := 'test_schedule2',
    par_enabled := 1::smallint,
    par_freq_type := 4,
    par_freq_interval := 1,
    par_freq_subday_type := 4,
    par_freq_subday_interval := 1,
    par_freq_relative_interval := 0,
    par_freq_recurrence_factor := 0,
    par_active_start_date := 20100801,
    par_active_end_date := 99991231,
    par_active_start_time := 0,
    par_active_end_time := 0);
```

## 在 PostgreSQL 中模拟 SQL Server Agent 的使用案例示例
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.UseCases"></a>

如果您的源数据库代码使用 SQL Server 代理来运行作业，则可以使用 SQL Server 到 PostgreSQL 扩展包 AWS SCT 将此代码转换为 PostgreSQL。扩展包使用 AWS Lambda 函数来模拟 SQL Server 代理的行为。

您可以创建新 AWS Lambda 函数或注册现有函数。

**创建新 AWS Lambda 函数**

1. 在目标数据库树中 AWS SCT，打开上下文（右键单击）菜单，选择 “**应用扩展包**”，然后选择 P **ostgreSQL**。

   扩展包向导随即出现。

1. 在 **SQL Server Agent 模拟服务**选项卡上，执行以下操作：
   + 选择**创建 AWS Lambda 函数**。
   + 在**数据库登录名**中，输入目标数据库用户名。
   + 在**数据库密码**中，输入您在上一步中输入的用户名的密码。
   + 对于 **Python 库文件夹**，请输入 Python 库文件夹的路径。
   + 选择 “**创建 AWS Lambda 函数**”，然后选择 “**下一步**”。

**注册之前部署的 AWS Lambda 函数**
+ 在目标数据库上运行以下脚本。

  ```
  SELECT
      FROM aws_sqlserver_ext.set_service_setting(
          p_service := 'JOB', 
          p_setting := 'LAMBDA_ARN', 
          p_value := ARN)
  ```

  在上述示例中，*`ARN`* 是已部署 AWS Lambda 函数的 Amazon 资源名称（ARN）。

以下示例创建了一个由一个步骤组成的简单任务。此任务每五分钟运行一次先前创建的 `job_example` 函数。此函数将记录插入 `job_example_table` 表中。

**创建这个简单的任务**

1. 使用 `aws_sqlserver_ext.sp_add_job` 函数创建作业，如下所示。

   ```
   SELECT
       FROM aws_sqlserver_ext.sp_add_job (
           par_job_name := 'test_simple_job');
   ```

1. 使用 `aws_sqlserver_ext.sp_add_jobstep` 函数创建任务步骤，如下所示。

   ```
   SELECT
       FROM aws_sqlserver_ext.sp_add_jobstep (
           par_job_name := 'test_simple_job', 
           par_step_name := 'test_simple_job_step1', 
           par_command := 'PERFORM job_simple_example;');
   ```

   作业步骤指定函数的用途。

1. 使用 `aws_sqlserver_ext.sp_add_jobschedule` 函数为作业创建计划程序，如下所示。

   ```
   SELECT
       FROM aws_sqlserver_ext.sp_add_jobschedule (
           par_job_name := 'test_simple_job', 
           par_name := 'test_schedule', 
           par_freq_type := 4, /* Daily */
           par_freq_interval := 1, /* frequency_interval is unused */
           par_freq_subday_type := 4, /* Minutes */
           par_freq_subday_interval := 5 /* 5 minutes */);
   ```

   作业步骤指定函数的用途。

要删除此作业，请使用如下所示的 `aws_sqlserver_ext.sp_delete_job` 函数。

```
PERFORM aws_sqlserver_ext.sp_delete_job(
    par_job_name := 'PeriodicJob1'::character varying,
    par_delete_history := 1::smallint,
    par_delete_unused_schedule := 1::smallint);
```