Run the operating system command in Oracle

zhaozj2021-02-08  249

In Oracle 8i, it is often necessary to run the operating system command during the stored procedure. In general, this can be achieved when using Oracle Enterprise Manager to set the job. However, because OEMs lack flexibility, set The parameters of the job are fixed. In practical applications, it is often necessary to run the operating system command at any time in the SQL statement. Oracle 8i does not run the os command, we can use the DBMS_PIPE package to implement this requirement.

DBMS_PIPE allows at least two processes to communicate. Oracle's pipelines are conceptually identical to the pipeline of the operating system, but in different mechanisms.

The following describes the specific steps:

1 Create a package, just name the daemon, the SQL statement is as follows:

/ * Create a DAEMON package * /

Create or Replace Package Body Daemon As

/ * EXECUTE_SYSTEM is a function that implements the run OS command * /

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);

/ * Send characters to the DAEMON pipeline * /

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;

/ * Get the return result * /

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 is to 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 THENRAISE_APPLICATION_ERROR (-20030,

'stop: error while sending. status =' || status);

END IF;

End stop;

End daemon;

Run the above statement through SQL * Plus, you will create a DAEMON package for the current user.

2 Create a daemon running on the OS, listens to the statement of the DAEMON package from the above DAEMON package. The following Pro * c code must be pre-prepared first by Pro * C.

#include

#include

EXEC SQL include Sqlca;

EXEC SQL Begin Declare Section;

Char * uid = "scott / tiger"; / * Change users, password, service name * / in this place

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 SQLEC DO Connect_ERROR ();

EXEC SQL Connect: UID;

Printf ("Daemon Connected./N");

EXEC SQL WHENEVER SQLEC SQL_ERROR ();

Printf ("daemon waiting ... / n");

While (1) {

EXEC SQL EXECUTE

Begin

/ * Receive the character sent by DEAMON * /

: status: = dbms_pipe.receive_message ('daemon');

IF: status = 0 THEN

/ * Take the character * /

DBMS_PIPE.UNPACK_MESSAGE (: Command);

END IF;

END;

End-exec;

IF (status == 0)

{

Command.arr [command.len] = '/ 0';

/ * If it is STOP, the process exits * /

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);

/ * Run OS command * /

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);

}

The above code is named Daemon.PC, pre-compiled with PROC:

Proc iname = daemon.pc userid = username / password @ service name SQLCHECK = Semantics

Get Daemon.c, compile with C, pay attention to add ORASQL8.LIB on NT, otherwise compiling, the connection cannot be passed.

3 Run daemon.exe on the server

4 Run the test statement in SQLPLUS:

SQL> Variable RV Number

SQL> EXECUTE: RV: = daemon.execute_system ('ls -la');

The PL / SQL process has been successfully completed.

SQL> EXECUTE: RV: = daemon.execute_system ('DIR');

The PL / SQL process has been successfully completed.

SQL>

DBMS_PIPE is used to see Oracle's documentation.

转载请注明原文地址:https://www.9cbs.com/read-2032.html

New Post(0)