[关闭]
@WrRan 2016-11-24T05:50:55.000000Z 字数 3451 阅读 1300

node-oracledb

10. PL/SQL Execution

PL/SQL stored procedures, functions and anonymous blocks can be called
from node-oracledb.

10.1 PL/SQL Stored Procedures

The PL/SQL procedure:

  1. CREATE OR REPLACE PROCEDURE myproc (id IN NUMBER, name OUT STRING) AS
  2. BEGIN
  3. SELECT last_name INTO name FROM employees WHERE employee_id = id;
  4. END;

can be called:

  1. . . .
  2. connection.execute(
  3. "BEGIN myproc(:id, :name); END;",
  4. { // bind variables
  5. id: 159,
  6. name: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 40 },
  7. },
  8. function (err, result)
  9. {
  10. if (err) { console.error(err.message); return; }
  11. console.log(result.outBinds);
  12. });

The output is:

  1. { name: 'Smith' }

Binding is required for IN OUT and OUT parameters. It is strongly
recommended for IN parameters. See
Bind Parameters for Prepared Statements.

10.2 PL/SQL Stored Functions

The PL/SQL function:

  1. CREATE OR REPLACE FUNCTION myfunc RETURN VARCHAR2 AS
  2. BEGIN
  3. RETURN 'Hello';
  4. END;

can be called by using an OUT bind variable for the function return value:

  1. . . .
  2. connection.execute(
  3. "BEGIN :ret := myfunc(); END;",
  4. { ret: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 40 } },
  5. function (err, result)
  6. {
  7. if (err) { console.error(err.message); return; }
  8. console.log(result.outBinds);
  9. });

The output is:

  1. { ret: 'Hello' }

See Bind Parameters for Prepared Statements for information on binding.

10.3 PL/SQL Anonymous PL/SQL Blocks

Anonymous PL/SQL blocks can be called from node-oracledb like:

  1. . . .
  2. connection.execute(
  3. "BEGIN SELECT last_name INTO :name FROM employees WHERE employee_id = :id; END;",
  4. { // bind variables
  5. id: 134,
  6. name: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 40 },
  7. },
  8. function (err, result)
  9. {
  10. if (err) { console.error(err.message); return; }
  11. console.log(result.outBinds);
  12. });

The output is:

  1. { name: 'Rogers' }

See Bind Parameters for Prepared Statements for information on binding.

10.4 Using DBMS_OUTPUT

The
DBMS_OUTPUT
package is the standard way to "print" output from PL/SQL. The way
DBMS_OUTPUT works is like a buffer. Your Node.js application code
must first turn on DBMS_OUTPUT buffering for the current connection by
calling the PL/SQL procedure DBMS_OUTPUT.ENABLE(NULL). Then any
PL/SQL executed by the connection can put text into the buffer using
DBMS_OUTPUT.PUT_LINE(). Finally DBMS_OUTPUT.GET_LINE() is used to
fetch from that buffer. Note, any PL/SQL code that uses DBMS_OUTPUT
runs to completion before any output is available to the user. Also,
other database connections cannot access your buffer.

A basic way to fetch DBMS_OUTPUT with node-oracledb is to bind an
output string when calling the PL/SQL DBMS_OUTPUT.GET_LINE()
procedure, print the string, and then repeat until there is no more
data. The following snippet is based on the example
dbmsoutputgetline.js:

  1. function fetchDbmsOutputLine(connection, cb) {
  2. connection.execute(
  3. "BEGIN DBMS_OUTPUT.GET_LINE(:ln, :st); END;",
  4. { ln: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 32767 },
  5. st: { dir: oracledb.BIND_OUT, type: oracledb.NUMBER } },
  6. function(err, result) {
  7. if (err) {
  8. return cb(err, connection);
  9. } else if (result.outBinds.st == 1) { // no more output
  10. return cb(null, connection);
  11. } else {
  12. console.log(result.outBinds.ln);
  13. return fetchDbmsOutputLine(connection, cb);
  14. }
  15. });
  16. }

Another way is to wrap the DBMS_OUTPUT.GET_LINE() call into a
pipelined function and fetch the output using a SQL query. See
dbmsoutputpipe.js for the full example.

The pipelined function could be created like:

  1. CREATE OR REPLACE TYPE dorow AS TABLE OF VARCHAR2(32767);
  2. /
  3. CREATE OR REPLACE FUNCTION mydofetch RETURN dorow PIPELINED IS
  4. line VARCHAR2(32767);
  5. status INTEGER;
  6. BEGIN LOOP
  7. DBMS_OUTPUT.GET_LINE(line, status);
  8. EXIT WHEN status = 1;
  9. PIPE ROW (line);
  10. END LOOP;
  11. END;
  12. /

To get DBMS_OUTPUT that has been created, simply execute the query
using the same connection:

  1. connection.execute(
  2. "SELECT * FROM TABLE(mydofetch())",
  3. [],
  4. { resultSet: true },
  5. function (err, result) {
  6. . . .

The query rows can be handled using a
ResultSet.

Remember to first enable output using DBMS_OUTPUT.ENABLE(NULL).

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注