0
0

More than 3 years have passed since last update.

Node.js + ibm_db + Db2 で、プレースホルダを用いたSQLを実行する

Last updated at Posted at 2020-04-15

プレースホルダを用いたSQLを使って、Db2にアクセスします。

SQLの条件指定を固定値(リテラル)で記述すると、指定される条件が変わるごとに新しいSQLとしてコンパイルされることになり、where条件だけが異なる同じSQLでパッケージ・キャッシュがあふれてしまいます。コンパイルにかかる時間ももったいない。
そうならないよう、可変となる値の部分だけ(場合によっては列名なども)、疑問符「?」で表したSQLで記述することができます。JDBCなどではパラメーターマーカーと呼ばれますが、Node.jsではプレースホルダと表現されるようです。

ここから先は、Db2を使う場合に、プレースホルダにどうやって値を渡すかのメモです。

プレースホルダーを用いたSQL実行例

ibm_dbのqueryでは、値を配列として渡します。

上(settings.js)は接続情報を渡すための外部ファイルの位置づけ。
下(test2.js) がテストプログラム本体です。

settings.js
exports.host = 'localhost';
exports.port = 50000;
exports.dbname = 'TESTDB';
exports.username = 'db2inst1';
exports.password = 'xxxxxxxx';
test2.js
var ibm_db = require( 'ibm_db' );
var settings = require( './settings' );

var db_con_str =
"DRIVER={DB2}"
  + ";DATABASE=" + settings.dbname
  + ";HOSTNAME=" + settings.host
  + ";PORT=" + settings.port
  + ";PROTOCOL=TCPIP"
  + ";UID=" + settings.username
  + ";PWD=" + settings.password
;

var sql_str = "select C1, C2 from db2inst1.T3 where C1=?";
var param1 = [1];  ← ココで、「C1=??に与える値を記述

ibm_db.open( db_con_str, function( err, conn ){
  if( err ) return console.log( err );

  conn.query( sql_str, param1, function( err, data ){
    if( err ) console.log( err );

    console.log( data );

    conn.close( function(){
      console.log( 'done' );
    });
  });
});

実行結果

$ node test2.js
[ { C1: 1, C2: 'a       ' } ]
done

なお、今回指定した値1は、データベース上は数値列(Integer)ですが、配列には文字列として記述してもちゃんと動きます。

var sql_str = "select C1, C2 from db2inst1.T3 where C1=?";
var param1 = ["1"];

失敗ケース その1(数値として渡した場合)

他のDBで検証されている例を見ていると、ただの数値でも問題なさそうなのですが
ibm_db では失敗します。

抜粋(SQL/プレースホルダ)
var sql_str = "select C1, C2 from T3 where C1=?";
var param1 = 1;

実行結果:

$ node test2.js
[Error: [IBM][CLI Driver] CLI0100E  Wrong number of parameters. SQLSTATE=07001] {
  error: '[node-ibm_db] SQL_ERROR',
  sqlcode: -99999,
  message: '[IBM][CLI Driver] CLI0100E  Wrong number of parameters. SQLSTATE=07001',
  state: '07001'
}
[]
done

失敗ケース その2(文字列として渡した場合)

文字列としてダブルクオートで囲むパターンも試しましたがうまくいかず。
※ "1" ではなく ["1"] と記述し、文字列配列として指定すれば成功します

抜粋(SQL/プレースホルダ)
var sql_str = "select C1, C2 from T3 where C1=?";
var param1 = "1";

実行結果:

node test2.js
/database/config/db2inst1/node_modules/ibm_db/lib/odbc.js:600
        self.conn.query(query, params, cbQuery);
                  ^

TypeError: Argument 1 must be an Array.
    at /database/config/db2inst1/node_modules/ibm_db/lib/odbc.js:600:19
    at SimpleQueue.next (/database/config/db2inst1/node_modules/ibm_db/lib/simple-queue.js:34:5)
    at SimpleQueue.maybeNext (/database/config/db2inst1/node_modules/ibm_db/lib/simple-queue.js:22:10)
    at SimpleQueue.push (/database/config/db2inst1/node_modules/ibm_db/lib/simple-queue.js:15:8)
    at Database.query (/database/config/db2inst1/node_modules/ibm_db/lib/odbc.js:470:14)
    at /database/config/db2inst1/work/node/test2.js:19:8
    at /database/config/db2inst1/node_modules/ibm_db/lib/odbc.js:111:11
    at /database/config/db2inst1/node_modules/ibm_db/lib/odbc.js:333:11
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0