创建新文件时如何编写数据库触发器?

时间:2013-12-26 09:52:57

标签: linux oracle plsql

我有一个创建&将日志存储在文件夹中。 我需要识别新日志,解析它们并用解析文件的内容更新DB。

如何识别新日志文件并触发触发器? (unix / linux盒子上的服务器) 日志的文件名不包含时间戳。而且,我有超过100个请求在1分钟内落入文件夹。 文件名包含唯一的订单ID&源目的地组件。

日志文件夹的结构按日期排序:

X
|__2013
      |__12
          |__31
              |__LOG_FROMCOMP_TOCOMP_ORDERID.TXT

我无法更新应用程序以更新数据库,并且日志文件夹对于许多组件是通用的。我应该解析日志文件夹,然后相应地更新数据库。

1 个答案:

答案 0 :(得分:1)

  

“我有超过100个请求落入1中的文件夹   分“

换句话说,你有一个设计糟糕的应用程序应该有一个基于消息的架构,但仍然在20世纪90年代初陷入困境。 Commiserations。

另外,文件名被选择为尽可能无益。 Commiserations加倍。

进一步的坏消息:数据库很难像这样处理目录结构。 Oracle安全模型需要已知的操作系统目录;如果你每天都在创建一个新的目录,而这个目录不是目录对象可持续的,那就排除了外部表的使用(将文件加载到我们数据库中的最简单方法)。

那么,可以做些什么呢?两个选择

  1. shell脚本调用PL / SQL
  2. 调用PL / SQL的Java存储过程
  3. shell脚本编写方法将涉及定期(通过cron或其他)触发的守护程序脚本,它会找出当前目录并查找自上次轮询以来添加的文件。 shell脚本需要将其执行时间存储在配置文件中。这里的皱纹是unix不存储文件创建时间。但是,如果您可以依赖于一次编写的文件并且从未更新,则可以使用ls -c对文件进行排序并按存储的执行时间对其进行过滤。

    对于每个文件,shell脚本调用PL / SQL过程。它将文件的内容作为CLOB传递。存储过程根据需要处理文件。

    要从数据库中控制所有内容,您需要使用Java存储过程来读取目录。 Tom Kyte有一个解决方案,可以填充临时表,您可以根据自己的需要进行调整。 Find it here。您需要再次派生实际目录。

    在这种方法中,JSP通过DBMS_JOB调用,并为每个文件调用PL / SQL progarm;它传递完整的文件路径,存储过程使用UTL_FILE来读取文件。请注意,这意味着说服您的DBA在init.ora文件中设置UTL_FILE_DIR参数。这是弃用的,所以期待一些阻力。但是,它需要通配符,因此它是处理动态目录名称的唯一方法。 Find out more

    JSP将列出临时表中的所有文件。这里的一个解决方案是拥有一个永久表,其中包含所有已处理文件的名称,并使用MINUS运算符提取未处理文件集。这比依赖shell脚本方法中的unix ctime更可靠。


    正如您所拥有的消息传递体系结构一样,您有第三种选择:而不是在永久更改目录中删除单个文件,而是使用前进排队。显然,发送附加消息确实需要对应用程序进行一些更改,但我希望是最小的一个。 AQ绝对比我上面提出的任何解决方案更整洁。 Find out more