[关闭]
@WrRan 2016-11-17T09:01:46.000000Z 字数 4482 阅读 2534

node-oracledb

11. Working with CLOB and BLOB Data

The Lob Class in node-oracledb implements the
Node.js Stream interface to provide
read and write access to CLOB and BLOB database columns and PL/SQL
bind parameters. Note, currently only BIND_OUT is supported for LOB bind
parameters.

It is the application's responsibility to make sure the connection is
not released while a Lob operation such as pipe() is in progress.

Readable Lobs

Being a Stream object, a Lob being read from the database has two
modes of operation: "flowing mode" and "paused mode". In flowing mode
data is piped to another stream, or events are posted as data is read.
In paused mode the application must explicitly call read() to get
data.

The read(size) unit is in characters for CLOBs and in bytes for BLOBs.

When reading a LOB from the database, make sure to fetch all data.
Resources are only released at completion of the read or if there is a
LOB error.

A Readable Lob object starts out in paused mode. If a 'data' event
handler is added, or the Lob is piped to a Writeable stream, then the
Lob switches to flowing mode.

For unpiped Readable Lobs operating in flowing mode where the Lob is
read through event handlers, the Lob object can be switched to paused
mode by calling pause(). Once the Lob is in paused mode, it stops
emitting data events.

Similarly, a Readable Lob operating in the paused mode can be switched
to flowing mode by calling resume(). It will then start emitting
'data' events again.

Writeable Lobs

Lobs are written to the database with pipe(). Alternatively the
write() method can be called successively, with the last piece being
written by the end() method. The end() method must be called
because it frees resources. If the Lob is being piped into, then the
write() and end() methods are automatically called.

Writeable Lobs also have events, see the
Node.js Stream documentation.

Examples

There are runnable LOB examples in the GitHub
examples
directory.

The following code is based on example
clobinsert1.js.
It shows inserting text into an Oracle Database CLOB column using
flowing mode. It first inserts an EMPTY_CLOB() and uses a
RETURNING INTO clause to pass the new LOB locator to node-oracledb,
where it is available as an instance of the Lob Class. A
Stream pipe() call loads data into the LOB. The data is committed
when the 'end' event fires, indicating the load has completed.
Autocommit is disabled when getting the locator because a transaction
must be open until the LOB data is inserted. In this example the
input data stream is simply a file on disk. Both the Lob stream and
input data stream have 'error' events to handle unexpected issues:

  1. var oracledb = require('oracledb');
  2. . . .
  3. connection.execute(
  4. "INSERT INTO mylobs (id, c) VALUES (:id, EMPTY_CLOB()) RETURNING c INTO :lobbv",
  5. { id: 1, lobbv: {type: oracledb.CLOB, dir: oracledb.BIND_OUT} },
  6. { autoCommit: false }, // a transaction needs to span the INSERT and pipe()
  7. function(err, result)
  8. {
  9. if (err) { console.error(err.message); return; }
  10. if (result.rowsAffected != 1 || result.outBinds.lobbv.length != 1) {
  11. console.error('Error getting a LOB locator');
  12. return;
  13. }
  14. var lob = result.outBinds.lobbv[0];
  15. lob.on('error', function(err) { console.error(err); });
  16. lob.on('finish',
  17. function()
  18. {
  19. connection.commit(
  20. function(err)
  21. {
  22. if (err)
  23. console.error(err.message);
  24. else
  25. console.log("Text inserted successfully.");
  26. connection.close(function(err) {
  27. if (err) console.error(err.message);
  28. });
  29. });
  30. });
  31. console.log('Reading from ' + inFileName);
  32. var inStream = fs.createReadStream(inFileName);
  33. inStream.on('error',
  34. function(err)
  35. {
  36. console.error(err);
  37. connection.close(function(err) {
  38. if (err) console.error(err.message);
  39. });
  40. });
  41. inStream.pipe(lob); // copies the text to the CLOB
  42. });
  43. ```
  44. The `EMPTY_CLOB()` / `RETURNING INTO` sequence is used because
  45. node-oracledb currently does not support temporary LOBs and `BIND_IN`
  46. for LOBs. A similar sequence is used to update LOBs.
  47. The following example shows selecting a CLOB using flowing mode and
  48. writing it to a file. It is similar to the example
  49. [`clobstream1.js`](https://github.com/oracle/node-oracledb/tree/master/examples/clobstream1.js).
  50. The returned column value is a Lob stream which is piped to an opened
  51. file stream.
  52. By default the Lob stream is a Node.js buffer - which is useful for
  53. BLOB data. Since this example uses a CLOB, the `setEncoding()` call
  54. is used to indicate data should be a string. Both the Lob stream and
  55. output data stream have 'error' events to handle unexpected issues:
  56. ```javascript
  57. var oracledb = require('oracledb');
  58. . . .
  59. connection.execute(
  60. "SELECT c FROM mylobs WHERE id = :id",
  61. { id: 1 },
  62. function(err, result)
  63. {
  64. if (err) { console.error(err.message); return; }
  65. if (result.rows.length === 0) { console.log("No results"); return; }
  66. var lob = result.rows[0][0];
  67. if (lob === null) { console.log("CLOB was NULL"); return; }
  68. lob.setEncoding('utf8'); // we want text, not binary output
  69. lob.on('error', function(err) { console.error(err); });
  70. lob.on('close', function() {
  71. connection.close(function(err) { if (err) console.error(err.message); });
  72. });
  73. console.log('Writing to ' + outFileName);
  74. var outStream = fs.createWriteStream(outFileName);
  75. outStream.on('error', function(err) { console.error(err); });
  76. lob.pipe(outStream);
  77. });
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注