在Oracle i中往往会出现要在存储过程中运行操作系统命令的情况一般来说利用Oracle EntERPrise Manager设定作业时可以达到这个目的但是由于OEM在设定作业缺乏灵活性设定的作业的参数是固定的在实际应用当中往往需要在SQL语句当中运行需要随时运行操作系统命令Oracle i没有直接运行OS命令的语句我们可以利用DBMS_PIPE程序包实现这一要求
DBMS_PIPE通过创建管道可以让至少两个进程进行通信Oracle的管道与操作系统的管道在概念上有相同的地方但是在实现机制不同
下面介绍实现具体步骤:
创建一个程序包姑且起名叫DAEMONSQL语句如下:
/*创建daemon程序包*/
CREATE OR REPLACE PACKAGE BODY daemon AS
/*execute_system是实现运行os命令的函数*/
FUNCTION execute_system(command VARCHAR
timeout NUMBER DEFAULT )
RETURN NUMBER IS
status NUMBER
result VARCHAR()
command_code NUMBER
pipe_name VARCHAR()
BEGIN
pipe_name := DBMS_PIPEUNIQUE_SESSION_NAME
DBMS_PIPEPACK_MESSAGE(SYSTEM)
DBMS_PIPEPACK_MESSAGE(pipe_name)
DBMS_PIPEPACK_MESSAGE(command)
/*向daemon管道发送表示命令的字符*/
status := DBMS_PIPESEND_MESSAGE(daemon timeout)
IF status <> THEN
RAISE_APPLICATION_ERROR(
Execute_system: Error while sending Status = || status)
END IF [page]
status := DBMS_PIPERECEIVE_MESSAGE(pipe_name timeout)
IF status <> THEN
RAISE_APPLICATION_ERROR(
Execute_system: Error while receiving
Status = || status)
END IF
/*获取返回结果*/
DBMS_PIPEUNPACK_MESSAGE(result)
IF result <> done THEN
RAISE_APPLICATION_ERROR(
Execute_system: Done not received)
END IF
DBMS_PIPEUNPACK_MESSAGE(command_code)
DBMS_OUTPUTPUT_LINE(System command executed result = ||
command_code)
RETURN command_code
END execute_system
/*stop是让daemon停止*/
PROCEDURE stop(timeout NUMBER DEFAULT ) IS
status NUMBER
BEGIN
DBMS_PIPEPACK_MESSAGE(STOP)
status := DBMS_PIPESEND_MESSAGE(daemon timeout)
IF status <> THEN
RAISE_APPLICATION_ERROR(
stop: error while sending status = || status)
END IF
END stop
END daemon
通过Sql*Plus运行以上语句将为当前用户创建daemon程序包
创建在OS上运行的守护进程监听由上面的daemon程序包发来的要求执行os命令的语句以下Pro*C的代码必须由pro*c先进行预编译
#include
#include
EXEC SQL INCLUDE SQLCA
EXEC SQL BEGIN DECLARE SECTION
char *uid = scott/tiger;/*在这个地方改为你自己访问的用户密码服务名*/
int status
VARCHAR command[]
VARCHAR value[]
VARCHAR return_name[]
EXEC SQL END DECLARE SECTION
void
connect_error()
{
char msg_buffer[]
int msg_length
int buffer_size =