请问:1、trigger 能否发送消息给外部进程或者管道什么的?
2、dbms_alert 如何发送消息给外部程序接收?
能有代码更好,消息的格式是什么?怎样接收?
在资料上只能查到如下:
当数据库中发生了一个事件时,用DBMS_ALERT包对一个会话提出警告,用户的会话登记所关心的事件,当该事件发生时,这个警告就给会话发出信号。该包中有以下几个模块。
名称 说明
REGISTER 注册登记用户的会话关心一个警告
REMOVE 告诉数据库用户的会话取消警告关联
REMOVEALL 从所有的警告注册表中删除用户的会话
SET_DEFAULTS 设置包开始一个检查循环时的等待事件
SIGNAL 发出警告已发生的信号
WAITANY 等待当前会话已注册的全部警告
WAITONE 等待某个特定警告的信号
通过DBMS_Alert包的使用,我们可以结合自定义的过程,在其中根据特定的操作执行Alert操作。可以达到很好的汇报目的。
2、dbms_alert 如何发送消息给外部程序接收?
能有代码更好,消息的格式是什么?怎样接收?
在资料上只能查到如下:
当数据库中发生了一个事件时,用DBMS_ALERT包对一个会话提出警告,用户的会话登记所关心的事件,当该事件发生时,这个警告就给会话发出信号。该包中有以下几个模块。
名称 说明
REGISTER 注册登记用户的会话关心一个警告
REMOVE 告诉数据库用户的会话取消警告关联
REMOVEALL 从所有的警告注册表中删除用户的会话
SET_DEFAULTS 设置包开始一个检查循环时的等待事件
SIGNAL 发出警告已发生的信号
WAITANY 等待当前会话已注册的全部警告
WAITONE 等待某个特定警告的信号
通过DBMS_Alert包的使用,我们可以结合自定义的过程,在其中根据特定的操作执行Alert操作。可以达到很好的汇报目的。
解决方案 »
- 求一个导出多用户多表空间的数据库方法
- Oracle 视图
- 为什么使用SQLPLUS 登录时会自动执行一段代码,并提示我输入变量值?????
- 表dba_role_privs和表dba_users的区别?
- 在oracle中 如何得到本机 的机器名??? 急!!!!
- 问高手一个问题????关于查询!
- 帮忙把一段sqlserver的函数转成oracle.
- 求救~出ORA-24909错!如何解决这个错误啊!
- Oracle连接不上???????出错于msvcrt.dll
- 请大家例举Oracle在什么情况下会出现CPU占用时间在90%以上???
- 如果设置OPTIMIZER_MODE=choose,oracle根据什么来决定是用all_rows还是first_rows来做执行计划?多谢各位指点迷津
- 监听程序打开出错?
可以看看 $ORACLE_HOME/OCI/SAMPLES/READPIPE.C.
里面有详细的例子。
要使用这些功能,必须知道各个功能的特点,根据需要选用。
警报和事务相关的,是异步发送的;管道是与事务无关的,是同步发送的。
警报的使用:
简单来说,警报是在服务器端发出,然后在客户端接收,这就需要在客户端有一个线程来监听警报。现在拿SQLPLUS做个例子,打开两个SQLPLUS,分别用提示符SQL1和SQL2表示。首先应先授予用户使用DBMS_ALERT的权限。登录到SYS用户下,执行一下语句:
GRANT EXECUTE ON DBMS_ALERT TO SCOTT;
--在一个SQLPLUS中(客户端)...
SQL1> set serveroutput on
SQL1> declare
2 l_status integer;
3 l_name varchar2(30);
4 l_msg varchar2(100);
5 begin
6 dbms_alert.register('a');--注册,对警报名称为'a'的警报感兴趣
7 dbms_alert.waitany(l_name,l_msg,l_status);
8 if l_status = 0 then
9 dbms_output.put_line('name:'||l_name);
10 dbms_output.put_line('msg:'||l_msg);
11 end if;
12 dbms_alert.removeall;
13 end;
14 /
--这时SQL1的会话将处于等待状态。在另一个SQLPLUS中(这是服务器端)
SQL2> exec dbms_alert.signal('a','bbb');PL/SQL 过程已成功完成。SQL2> commit;--必须提交事务,否则接收不到警报
--则在第一个SQLPLUS中显示如下:
name:A
msg:bbbPL/SQL 过程已成功完成。
SQL1>
基本的过程就是这样,具体的说明见Oracle Document。可以这么查看有关DBMS_ALERT包的信息:
set pagesize 0
set linesize 100
select text from all_source where name='DBMS_ALERT' AND TYPE='PACKAGE';在使用警报的过程中应注意以下几点:
1.客户端的接收线程应采用轮询的方式来监听警报,否则,当主线程退出时,将因为无法正常结束该监听子线程从而非正常退出引发资源泄漏的问题;
2.警报的名称和信息都是字符串,都是可以自定义的,只要发方和收方约定即可;
3.在事务非常频繁,在断时间内产生大量警报的时候,警报可能出现会因处理不及时而消失的现象,即如果服务器端连着发出了两个警报(即在很短的时间内提交了两次,警报名称相同,警报内容不同),而客户端来不及处理(比如客户端轮询警报肯定有时间间隔),那么客户端只能接收到后面一个警报,从而产生警报丢失的现象;可以参看SYS.DBMS_ALERT_INFO表,就知道为什么。这张表是用来存放所有要由客户端取走的警报的信息,其主键是(SID,NAME),即会话ID和警报名称,这样,当一客户端不能处理(接收)当前警报的时候,如果再来一个相同名称的警报,那么只有用后一条警报的信息修改前一条警报的信息啦。
4.一般用一个线程来专门接收警报,稍作处理后(如对警报名称和内容作简单解析),就将解析后的内容传给主线程进行处理,不要在监听线程中执行费时较长的操作。