プレースホルダを用いたSQLを使って、Db2にアクセスします。
SQLの条件指定を固定値(リテラル)で記述すると、指定される条件が変わるごとに新しいSQLとしてコンパイルされることになり、where条件だけが異なる同じSQLでパッケージ・キャッシュがあふれてしまいます。コンパイルにかかる時間ももったいない。
そうならないよう、可変となる値の部分だけ(場合によっては列名なども)、疑問符「?」で表したSQLで記述することができます。JDBCなどではパラメーターマーカーと呼ばれますが、Node.jsではプレースホルダと表現されるようです。
ここから先は、Db2を使う場合に、プレースホルダにどうやって値を渡すかのメモです。
プレースホルダーを用いたSQL実行例
ibm_dbのqueryでは、値を配列として渡します。
上(settings.js)は接続情報を渡すための外部ファイルの位置づけ。
下(test2.js) がテストプログラム本体です。
exports.host = 'localhost';
exports.port = 50000;
exports.dbname = 'TESTDB';
exports.username = 'db2inst1';
exports.password = 'xxxxxxxx';
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 では失敗します。
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"] と記述し、文字列配列として指定すれば成功します
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