【发布时间】:2019-10-03 18:52:36
【问题描述】:
这是this question的后续行动。
Oracle 从DBMS_SCHEDULER 执行eventcreate Windows 命令时遇到问题。
作为一种解决方法,我改为创建一个基本的 C# 应用程序来执行相同的 eventcreate 函数。它在基本层面上有效,但我面临一些障碍。
这是程序。 (我没有在这个问题中标记 C#,因为问题与 C# 无关。我只是将其作为信息提供。)
using System;
using System.Diagnostics;
class myEventCreateClass
{
public static void Main(String[] args)
{
using(EventLog eventLog = new EventLog("Application"))
{
eventLog.Source = "MySource";
eventLog.WriteEntry(args[0], EventLogEntryType.Warning, 218);
}
}
}
我将DBMS_SCHEDULER 作业修改为:
BEGIN
sys.dbms_scheduler.create_job(
job_name => 'SYS.TESTJOB',
job_type => 'EXECUTABLE',
job_action => 'C:\myEventCreate.exe',
job_class => 'DEFAULT_JOB_CLASS',
number_of_arguments => 1,
auto_drop => FALSE,
enabled => FALSE);
sys.dbms_scheduler.set_job_argument_value('SYS.TESTJOB', 1, 'testing123');
sys.dbms_scheduler.enable('SYS.TESTJOB');
END;
当我在 SYS 架构下手动运行此作业时,它成功地将一个事件放入 Windows 事件日志中,内容为:
testing123
这就是我成功的终点……
如果我在不同的架构下创建相同的作业(例如,将 SYS.TESTJOB 的所有实例更改为 MYSCHEMA.TESTJOB),它会在该架构中创建作业,但是当我尝试运行作业时(从任何架构)我得到以下一长串错误:
ORA-27370: job slave failed to launch a job of type EXECUTABLE
ORA-27300: OS system dependent operation:accessing job scheduler service failed with status: 2
ORA-27301: OS failure message: The system cannot find the file specified.
ORA-27302: failure occurred at: sjsec 6a
ORA-27303: additional information: The system cannot find the file specified.
ORA-06512: at "SYS.DBMS_ISCHED", line 185
ORA-06512: at "SYS.DBMS_SCHEDULER", line 486
ORA-06512: at line 1
当我尝试从MYSCHEMA 运行SYS.TESTJOB 时,它告诉我该作业不存在:
ORA-27476: "SYS.TESTJOB" does not exist
ORA-06512: at "SYS.DBMS_ISCHED", line 185
ORA-06512: at "SYS.DBMS_SCHEDULER", line 486
ORA-06512: at line 1
我怎样才能从SYS 以外的架构中获得这项工作?
还有一个问题(可能是更大的问题):我正在尝试从触发器内部运行此作业。
根据this question,更改DBMS_SCHEDULER 作业的设置(在我的情况下,我试图在每次运行作业之前更改作业参数)会导致Oracle 中隐含COMMIT,它不允许在触发器中使用。
对我来说,Oracle 甚至将这些标记为“参数”似乎是一种误导,因为参数的值在作业内部是固定的,而更改参数意味着更改作业本身。
无论如何,这个问题中公认的答案是使用DBMS_JOB,因为这并不隐含COMMIT,但我找不到使用DBMS_JOB 运行外部.exe 文件的方法。
因此,是否可以以某种方式修改此作业以允许动态作业参数?
我也对其他解决方案持开放态度,但从我所读到的内容来看,DBMS_SCHEDULER 似乎是实现这一目标的最佳方式。
根据要求,这里是我想要完成的一些背景:
在我的公司,我们进行了这样的设置,如果在某个来源(例如,在这种情况下,mySource,如提供的 C# 应用程序中所示)将条目放入 Windows 事件日志中,则会显示一条文本消息,其中包含用户日志消息的内容会自动发送到我自己和其他一些管理员的手机。
这非常有用,因为它可以立即通知我们发生了一些重要事件,并且我们可以准确控制我们想要包含哪些事件以及我们想要通知这些事件的哪些具体信息。
以下是我们目前通过短信收到通知的一些示例:
- 我们的任何自定义应用程序的停止或启动(以及谁停止/启动了它,如果它没有崩溃)。
- 当我们的任何自定义应用程序被纳入或脱离看门狗控制时(以及这样做的人)。
- 当某些“已知问题”出现或即将出现但我们尚未完全解决时。这使我们能够“领先于游戏”,以便我们可以主动处理它,而不是等待有人告诉我们。
我想将此功能扩展到我们的 Oracle 数据库中的某些事件(这就是为什么我试图根据 Oracle 中的触发器将事件放入事件日志的原因)。
到目前为止,我想到了一些希望通过短信通知我们的事情,所有这些都可以在触发器中确定:
当任何不在某个“已批准”用户列表中的人(可能是我们的管理员以及与 Oracle 连接的自定义应用程序)连接到我们的 Oracle 数据库时。这可以通过登录触发器来完成。 (实际上,我已经有了这个工作,因为登录触发器是由
SYS架构调用的,所以我没有遇到其他架构无法运行该作业的问题。但是......因为我仍然不能更改任何参数,我目前能做的最好的事情就是说"Someone" not approved logged into Oracle database...。如果我可以将用户名传递到 Windows 事件日志会更有用。)当我们的自定义应用程序之外的任何东西更改我们的 Oracle 数据库中的数据时。 (我们的自定义应用程序处理所有的插入/更新/删除等。只有在极少数情况下,我们才需要手动修改某些内容。我们希望在任何人 [包括我自己或其他管理员] 修改数据库的任何内容。)这可以通过每个表的更新/插入/删除触发器来完成。
【问题讨论】: