[Database, JavaScript] node-oracledb 0.7.0 now supports Result Sets and REF CURSORS

原文はこちら。
https://blogs.oracle.com/opal/entry/node_oracledb_0_7_0

Node.js driver for Oracle Databaseの新しいリリースがnpmjs.comやGitHubからご利用いただけるようになりました。
node-oracledb (npm)
https://www.npmjs.com/package/oracledb
node-oracledb (GitHub)
https://github.com/oracle/node-oracledb
node-oracledb 0.7はNode.js 0.10、Node.js 0.12、io.jsからOracle Databaseに接続できます。数多くのプラットフォームで動作しますnode-oracledbに関する詳細は、GitHubページをご覧ください。
0.7における変更点は以下の通りです。
  • 大きなデータセットの取得で結果セットが使えるようになりました。問い合わせ結果の行をResultsetクラスを使ってバッチで取得することができます。
    ResultSet class
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#resultsetclass
    これを使うことにより、大量の問い合わせ結果を一気に大量のメモリを使わず取得することができます。新たなgetRow()やgetRows()メソッドを繰り返し呼び出して問い合わせ結果をスクロールすることができます。
    getRow()
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#getrow
    getRows()
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#getrows
    一気にすべての行を返すというオリジナルのnode-oracledbの挙動は、デフォルトとして残っています。結果セットを返すには、新たなexecute()オプションである{ resultSet: true} を使う必要があります。以下はその例です。
  • //  (See the full code in examples/resultset2.js)
    
    . . .
    
    var numRows = 10;  // number of rows to return from each call to getRows()
    
    connection.execute(
      "SELECT employee_id, last_name FROM employees ORDER BY employee_id",
      [], // no bind variables
      { resultSet: true }, // return a result set.  Default is false
      function(err, result)
      {
        if (err) { . . . }
        fetchRowsFromRS(connection, result.resultSet, numRows);
      });
    });
    
    . . .
    
    function fetchRowsFromRS(connection, resultSet, numRows)
    {
      resultSet.getRows( // get numRows rows
        numRows,
        function (err, rows)
        {
          if (err) {
             . . .                        // close the result set and release the connection
          } else if (rows.length == 0) {  // no rows, or no more rows
            . . .                         // close the result set and release the connection
          } else if (rows.length > 0) {
            console.log(rows);
            fetchRowsFromRS(connection, resultSet, numRows);  // get next set of rows
          }
        });
    }
    
    もうデータがない、もしくはデータを使わなくなった場合には、新しい結果セットを閉じるclose()メソッドを使って結果セットを閉じることが重要です。
    close()
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#close
    Result Setsの詳細情報はマニュアルをご覧ください。
    Result Set Handling
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#resultsethandling
  • PL/SQLからの問い合わせ結果でREF CURSORが使えるようになりました。バインド変数を使ってREF CURSORの結果を返すPL/SQLコードは、新たなnode-oracledbの型であるOracledb.CURSORにバインドでき、新たなResultSetクラスを使って結果を取得することができます。
    //  (See the full code in examples/refcursor.js)
    
    var oracledb = require('oracledb');
    
    . . .
    
    var numRows = 10;  // number of rows to return from each call to getRows()
    
    var bindvars = {
      sal:  6000,
      cursor:  { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
    }
    
    connection.execute(
      "BEGIN get_emp_rs(:sal, :cursor); END;",  // The PL/SQL has an OUT bind of type SYS_REFCURSOR
      bindvars,
      function(err, result)
      {
        if (err) { . . . }
        fetchRowsFromRS(connection, result.outBinds.cursor, numRows);
      });
    
    . . .
    
    function fetchRowsFromRS(connection, resultSet, numRows)
    {
      resultSet.getRows( // get numRows rows
        numRows,
        function (err, rows)
        {
          if (err) {
             . . .                        // close the result set and release the connection
          } else if (rows.length == 0) {  // no rows, or no more rows
            . . .                         // close the result set and release the connection
          } else if (rows.length > 0) {
            console.log(rows);
            fetchRowsFromRS(connection, resultSet, numRows);  // get next set of rows
          }
        });
    }
    REF CURSORの利用に関する詳細情報は以下のマニュアルをご覧ください。
    REF CURSOR Bind Parameters
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#refcursors
  • 行のプリフェッチができるようになりました。新しいResultSetクラスでは新たな属性 oracledb.prefetchRows と新たな execute() オプションである refetchRows を通じてサポートします。
    oracledb.prefetchRows
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#propdbprefetchrows
    sexecute(): Options
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#executeoptions
    アプリケーションがOracle DatabaseからのResultSetの問い合わせ結果の行やREF CURSORの行を取得する都度、プリフェッチによって下位のOracle Databaseのライブラリに別の行を転送させることができます。これは、データベースやネットワークリソースのより有効な利用を促し、パフォーマンスやスケーラビリティに寄与します。プリフェッチサイズにかかわらず、アプリケーションへ返す行数は変化しません。基盤のOracleクライアントライブラリがバッファリングを司ります。
  • プリフェッチサイズのデフォルト値は100です。アプリケーションは各々のexecute()で所望のパフォーマンスを出すため、不要なメモリの割り当てや初期化を避けるために、プリフェッチサイズを調整すべきです。いくつかのTipsがマニュアルに記載されています。
    node-oracledb: Documentation for the Oracle Database Node.js Driver
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md
    node-oracledb 0.7.0では、非ResultSetクエリは現在プリフェッチサイズを固定値2でプリフェッチしています。これらのクエリで必要なラウンドトリップの回数を削減しています。
  • テストスィートを追加しました。ディレクトリのREADMEをご覧いただいて、テスト実行方法を確認してください。
    Testing node-oracledb
    https://github.com/oracle/node-oracledb/blob/master/test/README.md
    テストスィートを実行すると、各テストには識別が容易になるよう、固有の番号があることに気付くことでしょう。番号は連番とは限りません。
    Linux、Windowsでほとんどのテストをしています。環境やバージョンの違いに由来するテスト結果の差異を確認した場合は、OCAに署名し、修正とその修正が必要な理由とともに、pullリクエストを送ってください。詳細は以下のリンクをご覧ください。
    Contributing to node-oracledb
    https://github.com/oracle/node-oracledb/blob/master/CONTRIBUTING.md
    (OCAに署名後)新たなテストを提示する場合、各テストに対し、テスト済み領域に適用するドキュメント対象範囲のユニークな番号を割り当てます。
  • RETURNING INTOを使うSQL文のエラー処理を修正しました。同じエラーメッセージをレポートするDML RETURNING文を伴うすべてのエラーの発生原因であるバグを修正しました。
  • SQLにRETURNING INTO句がある場合の日付のINSERTを修正しました。INSERTを使ってdateやtimestampをインサートし、SQL句の文字もしくは数値列にRETURNING INTOが含まれる場合、エラーが出ていましたが、これを修正しました。
  • Renumbered the values used by the Oracledb Constantsが用いる値を再割り当てしました。アプリケーションがOracledb.OBJECTやOracledb.BIND_INOUTといった定数を使う場合、変更に気付かないかもしれませんが、何らかの理由で数値を例えば2のようにハードコーディングしている場合、この新しい数字を使って書き換える必要があります。詳細は以下のページをご覧ください。
    lib/oracledb.js
    https://github.com/oracle/node-oracledb/blob/master/lib/oracledb.js
    もしくは、よりよい方法としては、コードを定数を使って書き換えてください。

0 件のコメント:

コメントを投稿