|
在Oracle運(yùn)行操作系統(tǒng)命令
作者:heyongzhou | 來(lái)自:不詳 | 點(diǎn)擊:2065 | 發(fā)布:2001-11-8
在Oracle 8i中,往往會(huì)出現(xiàn)要在存儲(chǔ)過(guò)程中運(yùn)行操作系統(tǒng)命令的情況.一般來(lái)說(shuō),利用Oracle Enterprise Manager設(shè)定作業(yè)時(shí)可以達(dá)到這個(gè)目的.但是由于OEM在設(shè)定作業(yè)缺乏靈活性,設(shè)定的作業(yè)的參數(shù)是固定的.在實(shí)際應(yīng)用當(dāng)中往往需要在SQL語(yǔ)句當(dāng)中運(yùn)行需要隨時(shí)運(yùn)行操作系統(tǒng)命令.Oracle 8i沒(méi)有直接運(yùn)行OS命令的語(yǔ)句,我們可以利用DBMS_PIPE程序包實(shí)現(xiàn)這一要求.
DBMS_PIPE通過(guò)創(chuàng)建管道,可以讓至少兩個(gè)進(jìn)程進(jìn)行通信.Oracle的管道與操作系統(tǒng)的管道在概念上有相同的地方,但是在實(shí)現(xiàn)機(jī)制不同. 下面介紹實(shí)現(xiàn)具體步驟:
1 創(chuàng)建一個(gè)程序包,姑且起名叫DAEMON,SQL語(yǔ)句如下:
/*創(chuàng)建daemon程序包*/ CREATE OR REPLACE PACKAGE BODY daemon AS /*execute_system是實(shí)現(xiàn)運(yùn)行os命令的函數(shù)*/ FUNCTION execute_system(command VARCHAR2, timeout NUMBER DEFAULT 10) RETURN NUMBER IS
status NUMBER; result VARCHAR2(20); command_code NUMBER; pipe_name VARCHAR2(30); BEGIN pipe_name := DBMS_PIPE.UNIQUE_SESSION_NAME; DBMS_PIPE.PACK_MESSAGE(‘SYSTEM‘); DBMS_PIPE.PACK_MESSAGE(pipe_name); DBMS_PIPE.PACK_MESSAGE(command); /*向daemon管道發(fā)送表示命令的字符*/ status := DBMS_PIPE.SEND_MESSAGE(‘daemon‘, timeout); IF status <>; 0 THEN RAISE_APPLICATION_ERROR(-20010, ‘Execute_system: Error while sending. Status = ‘ || status); END IF;
status := DBMS_PIPE.RECEIVE_MESSAGE(pipe_name, timeout); IF status <>; 0 THEN RAISE_APPLICATION_ERROR(-20011, ‘Execute_system: Error while receiving. Status = ‘ || status); END IF; /*獲取返回結(jié)果*/ DBMS_PIPE.UNPACK_MESSAGE(result); IF result <>; ‘done‘ THEN RAISE_APPLICATION_ERROR(-20012, ‘Execute_system: Done not received.‘); END IF;
DBMS_PIPE.UNPACK_MESSAGE(command_code); DBMS_OUTPUT.PUT_LINE(‘System command executed. result = ‘ || command_code); RETURN command_code; END execute_system; /*stop是讓daemon停止*/ PROCEDURE stop(timeout NUMBER DEFAULT 10) IS status NUMBER; BEGIN DBMS_PIPE.PACK_MESSAGE(‘STOP‘); status := DBMS_PIPE.SEND_MESSAGE(‘daemon‘, timeout); IF status <>; 0 THEN RAISE_APPLICATION_ERROR(-20030, ‘stop: error while sending. status = ‘ || status); END IF; END stop; END daemon;
通過(guò)Sql*Plus運(yùn)行以上語(yǔ)句,將為當(dāng)前用戶創(chuàng)建daemon程序包.
2 創(chuàng)建在OS上運(yùn)行的守護(hù)進(jìn)程,監(jiān)聽(tīng)由上面的daemon程序包發(fā)來(lái)的要求執(zhí)行os命令的語(yǔ)句.以下Pro*C的代碼,必須由pro*c先進(jìn)行預(yù)編譯.
#include #include
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION; char *uid = "scott/tiger";/*在這個(gè)地方改為你自己訪問(wèn)的用戶,密碼,服務(wù)名*/ int status; VARCHAR command[20]; VARCHAR value[2000]; VARCHAR return_name[30]; EXEC SQL END DECLARE SECTION;
void connect_error() { char msg_buffer[512]; int msg_length; int buffer_size = 512;
EXEC SQL WHENEVER SQLERROR CONTINUE; sqlglm(msg_buffer, &buffer_size, &msg_length); printf("Daemon error while connecting:\n"); printf("%.*s\n", msg_length, msg_buffer); printf("Daemon quitting.\n"); exit(1); }
void sql_error() { char msg_buffer[512]; int msg_length; int buffer_size = 512;
EXEC SQL WHENEVER SQLERROR CONTINUE; sqlglm(msg_buffer, &buffer_size, &msg_length); printf("Daemon error while executing:\n"); printf("%.*s\n", msg_length, msg_buffer); printf("Daemon continuing.\n"); } main() { EXEC SQL WHENEVER SQLERROR DO connect_error(); EXEC SQL CONNECT :uid; printf("Daemon connected.\n");
EXEC SQL WHENEVER SQLERROR DO sql_error(); printf("Daemon waiting...\n"); while (1) { EXEC SQL EXECUTE BEGIN /*接收deamon發(fā)來(lái)的字符*/ :status := DBMS_PIPE.RECEIVE_MESSAGE(‘daemon‘); IF :status = 0 THEN /*取出字符*/ DBMS_PIPE.UNPACK_MESSAGE(:command); END IF; END; END-EXEC; IF (status == 0) { command.arr[command.len] = ‘\0‘; /*如果是stop,該進(jìn)程就退出*/ IF (!strcmp((char *) command.arr, "STOP")) { printf("Daemon exiting.\n"); break; }
ELSE IF (!strcmp((char *) command.arr, "SYSTEM")) { EXEC SQL EXECUTE BEGIN DBMS_PIPE.UNPACK_MESSAGE(:return_name); DBMS_PIPE.UNPACK_MESSAGE(:value); END; END-EXEC; value.arr[value.len] = ‘\0‘; printf("Will execute system command ‘%s‘\n", value.arr); /*運(yùn)行os命令*/ status = system(value.arr); EXEC SQL EXECUTE BEGIN DBMS_PIPE.PACK_MESSAGE(‘done‘); DBMS_PIPE.PACK_MESSAGE(:status); :status := DBMS_PIPE.SEND_MESSAGE(:return_name); END; END-EXEC;
IF (status) { printf ("Daemon error while responding to system command."); printf(" status: %d\n", status); } } ELSE { printf ("Daemon error: invalid command ‘%s‘ received.\n", command.arr); } } ELSE { printf("Daemon error while waiting for signal."); printf(" status = %d\n", status); } } EXEC SQL COMMIT WORK RELEASE; exit(0); } 以上代碼起名為daemon.pc,用proc預(yù)編譯:
proc iname=daemon.pc userid=用戶名/密碼@服務(wù)名 sqlcheck=semantics
得到daemon.c,在用c進(jìn)行編譯,注意在NT上要把orasql8.lib加上,否則編譯通過(guò),連接沒(méi)法通過(guò).
3 在服務(wù)器上運(yùn)行daemon.exe
4 在sqlplus運(yùn)行測(cè)試語(yǔ)句: SQL>; variable rv number SQL>; execute :rv := DAEMON.EXECUTE_SYSTEM(‘ls -la‘); PL/SQL 過(guò)程已成功完成。 SQL>; execute :rv := DAEMON.EXECUTE_SYSTEM(‘dir‘); PL/SQL 過(guò)程已成功完成。 SQL>;
DBMS_PIPE的用法見(jiàn)oracle的文檔.
| |
|
|