UNPKG

ibm_db

Version:

IBM DB2 and IBM Informix bindings for node

1,021 lines (813 loc) 92.2 kB
# ibm_db API Documentation ## Database APIs **APIs for creating and dropping Database using node.js application** * [.createDbSync(dbName, connectionString, [options])](#-ibmdb-createdbsyncdbname-connectionstring--options) * [.dropDBSync(dbName, connectionString)](#-ibmdb-dropdbsyncdbname-connectionstring--options) **Global (ibmdb) APIs** * [.open(connectionString [, options] [, callback])](#-1-ibmdb-openconnectionstring-options-callback) * [.openSync(connectionString [,options])](#-2-ibmdb-opensyncconnectionstring-options) * [.debug(value)](#-38-ibmdb-debugvalue) **Database APIs** * [.query(sqlQuery [, bindingParameters] [, callback])](#-3-database-querysqlquery--bindingparameters--callback) * [.querySync(sqlQuery [, bindingParameters])](#-4-database-querysyncsqlquery--bindingparameters) * [.queryStream(sqlQuery [, bindingParameters])](#-5-database-querystreamsqlquery--bindingparameters) * [.queryResult(sqlQuery, [, bindingParameters] [, callback])](#-6-database-queryresultsqlquery--bindingparameters--callback) * [.queryResultSync(sqlQuery [, bindingParameters])](#-7-database-queryresultsyncsqlquery--bindingparameters) * [.close([callback])](#-8-database-closecallback) * [.closeSync()](#-9-database-closesync) * [.prepare(sql [, callback])](#-10-database-preparesql--callback) * [.prepareSync(sql)](#-11-database-preparesyncsql) * [.beginTransaction([callback])](#-28-database-begintransactioncallback) * [.beginTransactionSync()](#-29-database-begintransactionsync) * [.commitTransaction([callback])](#-30-database-committransactioncallback) * [.commitTransactionSync()](#-31-database-committransactionsync) * [.rollbackTransaction([callback])](#-32-database-rollbacktransactioncallback) * [.rollbackTransactionSync()](#-33-database-rollbacktransactionsync) * [.setIsolationLevel(isolationLevel)](#-34-database-setisolationlevelisolationlevel) * [.executeFileSync(sqlFile, [delimiter], [outputFile])](#-39-database-executefilesyncsqlfile-delimiteroutputfile) * [.executeFile(sqlFile, [delimiter], [outputFile])](#-40-database-executefilesqlfile-delimiter-outputfile) * [.setAttr(attributeName, value [, callback])](#-41-database-setattrattributename-value--callback) * [.setAttrSync(attributeName, value)](#-42-database-setattrsyncattributename-value) * [.getInfo(infoType, [infoLength] [, callback])](#-43-database-getinfoinfotype-infolength--callback) * [.getInfoSync(infoType, [infoLength])](#-44-database-getinfosyncinfotype-infolength) * [.getTypeInfo(dataType [, callback])](#-45-database-gettypeinfodatatype--callback) * [.getTypeInfoSync(dataType)](#-46-database-gettypeinfosyncdatatype) * [.getFunctions(functionId, callback)](#-47-database-getfunctionsfunctionid-callback) * [.getFunctionsSync(functionId)](#-48-database-getfunctionssyncfunctionid) **ODBCStatement APIs** * [.bind(bindingParameters [, callback])](#-12-odbcstatement-bindbindingparameters--callback) * [.bindSync(bindingParameters)](#-13-odbcstatement-bindsyncbindingparameters) * [.execute([bindingParameters] [, callback])](#-14-odbcstatement-executebindingparameters--callback) * [.executeSync([bindingParameters])](#-15-odbcstatement-executesyncbindingparameters) * [.executeNonQuery([bindingParameters] [, callback])](#-16-odbcstatement-executenonquerybindingparameters--callback) * [.executeNonQuerySync([bindingParameters])](#-17-odbcstatement-executenonquerysyncbindingparameters) * [close([closeOption] [, callback])](#-18-odbcstatement-closecloseoption--callback) * [closeSync([closeOption])](#-19-odbcstatement-closesynccloseoption) **ODBCResult APIs** * [.fetch([option] [, callback])](#-20-odbcresult-fetchoption--callback) * [.fetchSync([option])](#-21-odbcresult-fetchsyncoption) * [.fetchAll([option] [, callback])](#-22-odbcresult-fetchalloption--callback) * [.fetchAllSync([option])](#-23-odbcresult-fetchallsyncoption) * [.fetchN(count [, option] [, callback])](#fetchNApi) * [.fetchNSync(count [, option])](#fetchNSyncApi) * [.getData([colNum] [, size] [, callback])](#-24-odbcresult-getdatacolnum--size--callback) * [.getDataSync(colNum, size)](#-25-odbcresult-getdatasynccolnum-size) * [.close([closeOption] [, callback])](#-26-odbcresult-closecloseoption--callback) * [.closeSync([closeOption])](#-27-odbcresult-closesynccloseoption) * [.getColumnNamesSync()](#-35-odbcresult-getcolumnnamessync) * [.getColumnMetadataSync()](#-36-odbcresult-getcolumnmetadatasync) * [.getSQLErrorSync()](#-37-odbcresult-getsqlerrorsync) * [.bindFileToCol(colNum, filePath [, fileOption] [, callback])](#bindFileToColApi) * [.bindFileToColSync(colNum, filePath [, fileOption])](#bindFileToColSyncApi) [**Connection Pooling APIs**](#connection-pooling-apis) * [.open(connectionString [, callback])](#-1-pool-openconnectionstring--callback) * [.openSync(connectionString)](#-2-pool-opensyncconnectionstring) * [.close([callback])](#-3-pool-closecallback) * [.closeSync()](#-4-pool-closesync) * [.init(N, connStr)](#-5-pool-initn-connstr) * [.initAsync(N, connStr [, callback])](#-6-pool-initasyncn-connstr--callback) * [.setMaxPoolSize(N)](#-7-pool-setmaxpoolsizen) ## [**bindingParameters**](#bindingparameters) ## [**CALL Statement**](#call-statement) ### <a name="openApi"></a> 1) (ibmdb) .open(connectionString [, options] [, callback]) Open a connection to a database. * **connectionString** - The connection string for your database. * For distributed platforms, the connection string is typically defined as: `DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=passwd` * For z/OS, the ODBC driver makes both local and remote connections using DSN, UID and PWD. The connection string is typically defined as: `DSN=dbname;UID=username;PWD=passwd`. To connect to remote Db2 databases, the connectivity information will need to be set up in the Communications Database (CDB). Please refer to scenario 1 in the following [article](https://www.ibm.com/developerworks/data/library/techarticle/0310chong/0310chong.html). For a complete list of supported configuration keywords, please refer to [CLI/ODBC configuration keywords](https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.apdv.cli.doc/doc/r0007964.html) * Selecting default schema is also supported using `CURRENTSCHEMA=schemaname;` (or CurrentSchema) * **options** - _OPTIONAL_ - Object type. Can be used to avoid multiple loading of native ODBC library for each call of `.open`. Also, can be used to pass connectTimeout value and systemNaming(true/false) for i5/OS server. * **callback** - _OPTIONAL_ - `callback (err, conn)`. If callback is not provided, a Promise will be returned. ```javascript const ibmdb = require("ibm_db") , connStr = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=passwd"; ibmdb.open(connStr, function (err, conn) { if (err) { console.log(err); return; } conn.query("select 1 from sysibm.sysdummy1", function (err1, rows) { if (err1) console.log(err1); else console.log(rows); conn.close(function(err2) { if(err2) console.log(err2); }); }); }); ``` * <a name="SSLConnection"></a> **Secure Database Connection using SSL/TSL** - ibm_db supports secure connection to Database Server over SSL same as ODBC/CLI driver. If you have SSL Certificate from server or an CA signed certificate, just use it in connection string as below: ```javascript connStr = "DATABASE=database;HOSTNAME=hostname;PORT=port;Security=SSL;SSLServerCertificate=<cert.arm_file_path>;PROTOCOL=TCPIP;UID=username;PWD=passwd;"; ``` > Note the two extra keywords **Security** and **SSLServerCertificate** used in connection string. `SSLServerCertificate` should point to the SSL Certificate from server or an CA signed certificate. Also, `PORT` must be `SSL` port and not the TCP/IP port. Make sure Db2 server is configured to accept connection on SSL port else `ibm_db` will throw SQL30081N error. > Value of `SSLServerCertificate` keyword must be full path of a certificate file generated for client authentication. It normally has `*.arm` or `*.cert` or `*.pem` extension. `ibm_db` do not support `*.jks` format file as it is not a certificate file but a Java KeyStore file, extract certificate from it using keytool and then use the cert file. > `ibm_db` uses IBM ODBC/CLI Driver for connectivity and it do not support a `*.jks` file as keystoredb as `keystore.jks` is meant for Java applications. Note that `*.jks` file is a `Java Key Store` file and it is not an SSL Certificate file. You can extract SSL certificate from JKS file using below `keytool` command: ``` keytool -exportcert -alias your_certificate_alias -file client_cert.cert -keystore keystore.jks ``` Now, you can use the generated `client_cert.cert` as the value of `SSLServerCertificate` in connection string. > `ibm_db` supports only ODBC/CLI Driver keywords in connection string: https://www.ibm.com/docs/en/db2/11.5?topic=odbc-cliodbc-configuration-keywords > Do not use keywords like `sslConnection=true` in connection string as it is a JDBC connection keyword and ibm_db ignores it. Corresponding ibm_db connection keyword for `sslConnection` is `Security` hence, use `Security=SSL;` in connection string instead. * To connect to dashDB in IBM Cloud, use below connection string: ``` connStr = "DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=passwd;Security=SSL"; ``` > We just need to add **Security=SSL** in connection string to have a secure connection against Db2 server in IBM Cloud. **Note:** You can also create a KeyStore DB using GSKit command line tool and use it in connection string along with other keywords as documented in [DB2 Infocenter](http://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.5.0/com.ibm.db2.luw.admin.sec.doc/doc/t0053518.html). If you have created a KeyStore DB using GSKit using password or you have got *.kdb file with *.sth file, use connection string in below format: ``` connStr = "DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=db2pwd;" + "Security=SSL;SslClientKeystoredb=C:/client.kdb;SSLClientKeystash=C:/client.sth;"; OR, connStr = "DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=db2pwd;" + "Security=SSL;SslClientKeystoredb=C:/client.kdb;SSLClientKeystoreDBPassword=kdbpasswd;"; ``` > If you have downloaded `IBMCertTrustStore` from IBM site, ibm_db will not work with it; you need to download `Secure Connection Certificates.zip` file that comes for IBM DB2 Command line tool(CLP). `Secure Connection Certificates.zip` has *.kdb and *.sth files that should be used as the value of `SSLClientKeystoreDB` and `SSLClientKeystash` in connection string. ### <a name="openSyncApi"></a> 2) (ibmdb) .openSync(connectionString [,options]) Synchronously open a connection to a database. * **connectionString** - The connection string for your database * **options** - _OPTIONAL_ - Object type. Can be used to avoid multiple loading of native ODBC library for each call of `.open`. Also, can be used to pass connectTimeout value and systemNaming value for i5/OS server. ```javascript const ibmdb = require("ibm_db"), connString = "DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=password;"; try { const option = { connectTimeout : 40, systemNaming : true };// Connection Timeout after 40 seconds. const conn = ibmdb.openSync(connString, option); conn.query("select * from customers fetch first 10 rows only", function (err, rows) { if (err) { console.log(err); } else { console.log(rows); } conn.close(); }); } catch (e) { console.log(e.message); } ``` ### <a name="queryApi"></a> 3) (Database) .query(sqlQuery [, bindingParameters] [, callback]) Issue an asynchronous SQL query to the database which is currently open. * **sqlQuery** - The SQL query to be executed or an Object in the form {"sql": sqlQuery, "params":bindingParameters, "noResults": noResultValue, "ArraySize": n}. noResults accepts only true or false values. If true - query() will not return any result. "sql" field is mandatory in Object, others are _OPTIONAL_. For **Column-wise Array Insert**, `ArraySize` must be passed and sqlQuery must be an object. Check [test-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-array-insert.js) for example. For **Row-wise Array Insert**, pass `rows` (array of row arrays) instead of `params` and `ArraySize`. Optionally pass `columns` for type metadata. Check [test-row-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-row-array-insert.js) for example. * **bindingParameters** - _OPTIONAL_ - An array of values that will be bound to any '?' characters in `sqlQuery`. bindingParameters in sqlQuery Object takes precedence over it. * **callback** - _OPTIONAL_ - `callback (err, rows, sqlca)`. If no callback is provided, query() will return a Promise. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=password;" ; ibmdb.open(cn, function (err, conn) { if (err) { return console.log(err); } // we now have an open connection to the database, so lets get some data. // Execute multiple query and get multiple result sets. // In case of multiple resultset, query will return an array of result sets. conn.query("select 1 from sysibm.sysdummy1;select 2 from sysibm.sysdummy1;" + "select 3 from sysibm.sysdummy1", function (err, rows, sqlca) { if (err) { console.log(err); } else { console.log(rows); // rows = [ [ { '1': 1 } ], [ { '1': 2 } ], [ { '1': 3 } ] ] } }); }); ``` Example for Array Insert: ```javascript const param1 = {ParamType:"ARRAY", DataType:1, Data:[4,5,6,7,8]}; const param2 = {ParamType:"ARRAY", DataType:"DOUBLE", Data:[4.1,5.3,6.14,7,8.3]}; const param3 = {ParamType:"ARRAY", DataType:1, Data:[0,1,false,true,0]}; const namearr = ["Row 10", "Row 203456", "Row 30", "Row 40", "Last Row"]; const param4 = {ParamType:"ARRAY", DataType:1, Data:namearr, Length:8}; // *** "Length" is optional. Default value is the max length among all // members of the Array. Use "Length: <customLen>" to override if needed. const queryOptions = {sql:"insert into arrtab values (?, ?, ?, ?)", params: [param1, param2, param3, param4], ArraySize:5}; conn.querySync("create table arrtab (c1 int, c2 double, c3 boolean, c4 varchar(10))"); conn.query(queryOptions, function(err, result) { if(err) console.log(err); else { const data = conn.querySync("select * from arrtab"); console.log("\nSelected data for table ARRTAB =\n", data); } }); ``` Example for Row-wise Array Insert: ```javascript // Row-wise array insert: pass data as rows instead of column-wise arrays. // Each element of the "rows" array is one row of values. // The driver automatically transposes rows to column-wise ARRAY parameters. conn.querySync("create table rowtab (c1 int, c2 double, c3 varchar(10))"); const rowOptions = {sql: "insert into rowtab values (?, ?, ?)", rows: [ [1, 10.5, "Row 1"], [2, 20.3, "Row 2"], [3, 30.7, "Row 3"] ]}; conn.query(rowOptions, function(err, result) { if(err) console.log(err); else { const data = conn.querySync("select * from rowtab"); console.log("\nSelected data for table ROWTAB =\n", data); } }); // Row-wise insert with columns metadata for type hints: const rowOptions2 = {sql: "insert into rowtab values (?, ?, ?)", columns: [ {DataType: "INTEGER"}, {DataType: "DOUBLE"}, {DataType: "VARCHAR", Length: 10} ], rows: [ [4, 40.1, "Row 4"], [5, 50.2, "Row 5"] ]}; conn.query(rowOptions2, function(err, result) { if(err) console.log(err); }); ``` ### <a name="querySyncApi"></a> 4) (Database) .querySync(sqlQuery [, bindingParameters]) Synchronously issue a SQL query to the database that is currently open. * **sqlQuery** - The SQL query to be executed or an Object in the form {"sql": sqlQuery, "params":bindingParameters, "noResults": noResultValue, "ArraySize": n}. noResults accepts only true or false values. If true - query() will not return any result. If noResults is true for CALL statement, querySync returns only OutParams. "sql" field is mandatory in Object, others are optional. For **Column-wise Array Insert**, `ArraySize` must be passed and sqlQuery must be an object. Check [test-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-array-insert.js) for example. For **Row-wise Array Insert**, pass `rows` (array of row arrays) instead of `params` and `ArraySize`. Optionally pass `columns` for type metadata. Check [test-row-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-row-array-insert.js) for example. * **bindingParameters** - _OPTIONAL_ - An array of values that will be bound to any '?' characters in `sqlQuery`. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=password"; ibmdb.open(cn, function(err, conn) { //blocks until the query is completed and all data has been acquired const rows = conn.querySync("select * from customers fetch first 10 rows only"); console.log(rows); }); ``` Example for Array Insert: ```javascript const param1 = {ParamType:"ARRAY", DataType:1, Data:[4,5,6,7,8]}; const param2 = {ParamType:"ARRAY", DataType:"DOUBLE", Data:[4.1,5.3,6.14,7,8.3]}; const param3 = {ParamType:"ARRAY", DataType:1, Data:[0,1,false,true,0]}; const namearr = ["Row 10", "Row 20", "Row 30", "Row 40", "Last Row"]; const param4 = {ParamType:"ARRAY", DataType:1, Data:namearr, Length:8}; // *** "Length" is optional. Default value is the max length among all // members of the Array. Use "Length: <customLen>" to override if needed. const queryOptions = {sql:"insert into arrtab values (?, ?, ?, ?)", params: [param1, param2, param3, param4], ArraySize:5}; conn.querySync("create table arrtab (c1 int, c2 double, c3 boolean, c4 varchar(10))"); conn.querySync(queryOptions); ``` Example for Row-wise Array Insert: ```javascript // Row-wise array insert: pass data as rows instead of column-wise arrays. conn.querySync("create table rowtab (c1 int, c2 double, c3 varchar(10))"); const rowOptions = {sql: "insert into rowtab values (?, ?, ?)", rows: [ [1, 10.5, "Row 1"], [2, 20.3, "Row 2"], [3, 30.7, "Row 3"] ]}; conn.querySync(rowOptions); const data = conn.querySync("select * from rowtab"); console.log(data); // With columns metadata: const rowOptions2 = {sql: "insert into rowtab values (?, ?, ?)", columns: [ {DataType: "INTEGER"}, {DataType: "DOUBLE"}, {DataType: "VARCHAR", Length: 10} ], rows: [ [4, 40.1, "Row 4"], [5, 50.2, "Row 5"] ]}; conn.querySync(rowOptions2); ``` Row-wise array insert using `ibmdb.convertRowsToColumns` with prepare/bind/execute: ```javascript // For prepare/bind/execute pattern, use ibmdb.convertRowsToColumns() // to convert rows to column-wise ARRAY params manually. const converted = ibmdb.convertRowsToColumns( [[10, "ten"], [20, "twenty"], [30, "thirty"]] ); const stmt = conn.prepareSync("insert into mytab values (?, ?)"); stmt.bindSync(converted.params); stmt.setAttrSync(ibmdb.SQL_ATTR_PARAMSET_SIZE, converted.ArraySize); stmt.executeSync(); stmt.closeSync(); ``` ### <a name="queryStreamApi"></a> 5) (Database) .queryStream(sqlQuery [, bindingParameters]) Synchronously issue a SQL query to the database that is currently open and returns a Readable stream. Application can listen for the events emitted by returned stream and take action. * **sqlQuery** - The SQL query to be executed or an Object in the form {"sql": sqlQuery, "params":bindingParameters, "noResults": noResultValue, "ArraySize": n}. noResults accepts only true or false values. If true - query() will not return any result. "sql" field is mandatory in Object, others are optional. For **Column-wise Array Insert**, `ArraySize` must be passed and sqlQuery must be an object. Check [test-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-array-insert.js) for example. For **Row-wise Array Insert**, pass `rows` instead of `params` and `ArraySize`. Check [test-row-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-row-array-insert.js) for example. * **bindingParameters** - _OPTIONAL_ - An array of values that will be bound to any '?' characters in `sqlQuery`. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn, function(err, conn) { const stream = conn.queryStream("select 1 from sysibm.sysdummy1"); stream.once('data', function (result) { console.log(result); }).once('error', function (err) { conn.closeSync(); throw err; }).once('end', function () { conn.close(function(){ console.log("done.") }); }); }); ``` ### <a name="queryResultApi"></a> 6) (Database) .queryResult(sqlQuery, [, bindingParameters] [, callback]) Issue an asynchronous SQL query to the database which is currently open and return `(err, result, outparams)` to callback function. `result` is ODBCResult object. Using `result`, call one of the `result.fetch*` APIs to retrieve rows. Call `result.getColumnMetadataSync()` to get meta data info. Execute `result.closeSync()` once done with the `result` object. `query` returns all the rows on call, but `queryResult` returns an `ODBCResult` object and rows need to be fetched by the caller. * **sqlQuery** - The SQL query to be executed or an Object in the form {"sql": sqlQuery, "params":bindingParameters, "noResults": noResultValue, "ArraySize": n}. noResults accepts only true or false values. If true - queryResult() will not return any result object and value of result will be null. "sql" field is mandatory in Object, others are _OPTIONAL_. For **Column-wise Array Insert**, `ArraySize` must be passed and sqlQuery must be an object. Check [test-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-array-insert.js) for example. For **Row-wise Array Insert**, pass `rows` instead of `params` and `ArraySize`. Check [test-row-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-row-array-insert.js) for example. * **bindingParameters** - _OPTIONAL_ - An array of values that will be bound to any ? characters (called parameter marker) in `sqlQuery`. bindingParameters in sqlQuery Object takes precedence over it. * **callback** - _OPTIONAL_ - `callback (err, result, outparams)`. outparams is returned only for CALL statement with OUT parameters. Any resultset expected from SP should get retrieved using the `result.fetch*` apis. If `callback` is not provided, queryResult() will return a Promise of `[result, outparams]`. `result` is an ODBCResult object that can be used to fetch rows. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=password;" ; ibmdb.open(cn, function (err, conn) { if (err) return console.log(err); const query = 'select creator, name from sysibm.systables where 1 = ?'; conn.queryResult(query, [1], function (err, result) { if(err) { console.log(err); } else { console.log("data = ", result.fetchAllSync()); console.log("metadata = ", result.getColumnMetadataSync()); result.closeSync(); // Must call in application. conn.closeSync(); console.log("Executed ", ++loop, " times."); } }); }); ``` **Note:** Once you are done with the `result` object, you must close it to avoid an error when the Javascript garbage collector frees it. Not calling `result.close()` or `result.closeSync()` may cause an invalid handle error in the application or no data. ### <a name="queryResultSyncApi"></a> 7) (Database) .queryResultSync(sqlQuery [, bindingParameters]) Synchronously issue a SQL query to the database that is currently open and return a result object to the callback function on success. In the case of CALL statement with OUT parameters, it returns an Array of `[result, outparams]`. `result` is an ODBCResult object that can be used to fetch rows. `querySync` returns all the rows on call, but `queryResultSync` returns an `ODBCResult` object and rows need to be fetched by the caller. * **sqlQuery** - The SQL query to be executed or an Object in the form {"sql": sqlQuery, "params":bindingParameters, "noResults": noResultValue, "ArraySize": n}. noResults accepts only true or false values. If true - the value of `result` will be null. "sql" field is mandatory in Object, others are optional. For **Column-wise Array Insert**, `ArraySize` must be passed and sqlQuery must be an object. Check [test-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-array-insert.js) for example. For **Row-wise Array Insert**, pass `rows` instead of `params` and `ArraySize`. Check [test-row-array-insert.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-row-array-insert.js) for example. * **bindingParameters** - _OPTIONAL_ - An array of values that will be bound to any '?' characters in `sqlQuery`. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=password"; ibmdb.open(cn, function(err, conn) { if (err) return console.log(err); const query = 'select creator, name from sysibm.systables'; const result = conn.queryResultSync(query); console.log("data = ", result.fetchAllSync()); console.log("metadata = ", result.getColumnMetadataSync()); result.closeSync(); // Must call to free to avoid application error. conn.closeSync(); }); ``` **Note:** Once you are done with the `result` object, you must close it to avoid an error when the Javascript garbage collector frees it. Not calling `result.close()` or `result.closeSync()` may cause an invalid handle error in the application or no data. In case of a CALL statement with OUT params, check whether result[0] is an object or not. ### <a name="closeApi"></a> 8) (Database) .close([callback]) Close the currently opened database. * **callback** - _OPTIONAL_ - `callback (err)`. If callback is not provided, a Promise will be returned. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn, function (err, conn) { if (err) { return console.log(err); } //we now have an open connection to the conn conn.close(function (err) { console.log("the database connection is now closed"); }); }); ``` ### <a name="closeSyncApi"></a> 9) (Database) .closeSync() Synchronously close the currently opened database. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn, function(err, conn) { if (err) return console.log(err); //Blocks until the connection is closed conn.closeSync(); }); const conn = ibmdb.openSync(connString, option); conn.closeSync(); ``` ### <a name="prepareApi"></a> 10) (Database) .prepare(sql [, callback]) Prepare a statement for execution. * **sql** - SQL string to prepare * **callback** - _OPTIONAL_ - `callback (err, stmt)`. If callback is not provided, a Promise will be returned. Returns an `ODBCStatement` object. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err, conn){ conn.prepare("insert into hits (col1, col2) VALUES (?, ?)", function (err, stmt) { if (err) { //could not prepare for some reason console.log(err); return conn.closeSync(); } //Bind and Execute the statement asynchronously stmt.execute(['something', 42], function (err, result) { if( err ) console.log(err); else result.closeSync(); //Close the connection conn.close(function(err){}); }); }); }); ``` ### <a name="prepareSyncApi"></a> 11) (Database) .prepareSync(sql) Synchronously prepare a statement for execution. * **sql** - SQL string to prepare Returns an `ODBCStatement` object. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err,conn){ const stmt = conn.prepareSync("select * from employee where empid = ?"); //Bind and Execute the statement asynchronously stmt.execute([142], function (err, result) { data = result.fetchAllSync(); console.log(data); result.closeSync(); stmt.closeSync(); //Close the connection conn.close(function(err){}); }); }); ``` ### <a name="bindApi"></a> 12) (ODBCStatement) .bind(bindingParameters [, callback]) Binds the parameters for the prepared statement. * **bindingParameters** - An array of values that will be bound to any '?' characters in prepared sql statement. Values can be array or object itself. Check [bindingParameters](#bindParameters) doc for detail. * **callback** - _OPTIONAL_ - `callback (err)`. If callback is not provided, a Promise will be returned. * For **ARRAY INSERT** - Each value should be an array of size passed as `ArraySize` in query() APIs or equal to the value of attribute SQL_ATTR_PARAMSET_SIZE set using setAttr() APIs for prepared statement. ### <a name="bindSyncApi"></a> 13) (ODBCStatement) .bindSync(bindingParameters) Binds the parameters for the prepared statement synchronously. If `bindSync()` is used, then there is no need to pass `bindingParameters` to the next `execute()` or `executeSync()` statement. * **bindingParameters** - An array of values that will be bound to any '?' characters in the prepared SQL statement. Values can be an array or object. See [bindingParameters](#bindParameters) for detail. * For **ARRAY INSERT** - Each value should be an array of size passed as `ArraySize` in query() APIs or equal to the value of attribute SQL_ATTR_PARAMSET_SIZE set using setAttr() APIs for prepared statement. ### <a name="executeApi"></a> 14) (ODBCStatement) .execute([bindingParameters] [, callback]) Execute a prepared statement. * **bindingParameters** - OPTIONAL - An array of values that will be bound to any '?' characters in prepared sql statement. Values can be an array or object. See [bindingParameters](#bindParameters) for detail. * **callback** - _OPTIONAL_ - `callback (err, result, outparams)`. If callback is not provided, a Promise will be returned. outparams - will have result for INOUT and OUTPUT parameters of Stored Procedure. * For **ARRAY INSERT** - Statement attribute SQL_ATTR_PARAMSET_SIZE must be set before calling execute() API. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err, conn){ conn.querySync("create table mytab (id int, photo BLOB(30K))"); conn.prepare("insert into mytab (id, photo) VALUES (?, ?)", function (err, stmt) { if (err) { //could not prepare for some reason console.log(err); return conn.closeSync(); } // Create params object const img = {ParamType:"FILE", DataType: "BLOB", "Data": "smile.jpg"}; //Bind and Execute the statement asynchronously stmt.execute([ 42, img ], function (err, result) { if( err ) console.log(err); else result.closeSync(); //Close the connection stmt.close(function(err){ if(err){ console.log(err) } conn.close(function(err){}); }); }); }); }); ``` ### <a name="executeSyncApi"></a> 15) (ODBCStatement) .executeSync([bindingParameters]) Execute a prepared statement synchronously. * **bindingParameters** - OPTIONAL - An array of values that will be bound to any '?' characters in prepared sql statement. Values can be an array or object. See [bindingParameters](#bindParameters) for detail. Instead of passing bindingParameters to executeSync(), parameters can also be bound using the `bind()` and `bindSync()` APIs. * For **ARRAY INSERT** - Statement attribute SQL_ATTR_PARAMSET_SIZE must be set before calling execute() API. Returns an `ODBCResult` object. If the prepared statement is a stored procedure with INOUT or OUT parameters, executeSync() returns an array of two elements in the form [stmt, outparams]. The first element of the array is an `ODBCResult` object and second element is an `Array` of INOUT and OUTPUT parameters in sequence. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err, conn){ const stmt = conn.prepareSync("select empname from emptable where empid = ?"); //Bind and Execute the statment asynchronously const result = stmt.executeSync([142]); const data = result.fetchAllSync({fetchMode:3}); // Fetch data in Array mode. console.log(data); result.closeSync(); stmt.closeSync(); //Close the connection conn.close(function(err){}); }); ``` ### <a name="executeNonQueryApi"></a> 16) (ODBCStatement) .executeNonQuery([bindingParameters] [, callback]) Executes a non query prepared statement and returns the number of rows affected in a table by the statement. * **bindingParameters** - OPTIONAL - An array of values that will be bound to any '?' characters in prepared sql statement. Values can be an array or object. See [bindingParameters](#bindParameters) for detail. * **callback** - _OPTIONAL_ - `callback (err, affectedRowCount)`. If callback is not provided, a Promise will be returned. * For **ARRAY INSERT** - Statement attribute SQL_ATTR_PARAMSET_SIZE must be set before calling execute() API. It returns the number of rows in a table that were affected by an UPDATE, an INSERT, a DELETE, or a MERGE statement issued against the table, or a view based on the table. If no rows are affected, it returns -1. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err, conn){ conn.querySync("create table mytab (id int, text varchar(30))"); conn.prepare("insert into mytab (id, text) VALUES (?, ?)", function (err, stmt) { if (err) { console.log(err); return conn.closeSync(); } //Bind and Execute the statment asynchronously stmt.executeNonQuery([ 42, 'hello world' ], function (err, ret) { if( err ) console.log(err); else console.log("Affected rows = " + ret); //Close the stmt and connection stmt.close(); conn.close(function(err){}); }); }); }); ``` ### <a name="executeNonQuerySyncApi"></a> 17) (ODBCStatement) .executeNonQuerySync([bindingParameters]) Executes a non query prepared statement synchronously and returns the number of rows affected in a table by the statement. * **bindingParameters** - OPTIONAL - An array of values that will be bound to any '?' characters in prepared sql statement. Values can be an array or object. See [bindingParameters](#bindParameters) for detail. * For **ARRAY INSERT** - Statement attribute SQL_ATTR_PARAMSET_SIZE must be set before calling execute() API. It returns the number of rows in a table that were affected by an UPDATE, an INSERT, a DELETE, or a MERGE statement issued against the table, or a view based on the table. If no rows are affected, it returns -1. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err, conn){ conn.querySync("create table mytab (id int, text varchar(30))"); conn.prepare("insert into mytab (id, text) VALUES (?, ?)", function (err, stmt) { if (err) { console.log(err); return conn.closeSync(); } //Bind and Execute the statment asynchronously const rowCount = stmt.executeNonQuerySync([ 42, 'hello world' ]); console.log("Affected rows = " + rowCount); //Close the stmt and connection stmt.closeSync(); conn.closeSync(); }); }); ``` ### <a name="stmtCloseApi"></a> 18) (ODBCStatement) close([closeOption] [, callback]) Close the currently opened statement object and free resources. * **callback** - _OPTIONAL_ - `callback (err)`. If callback is not provided, a Promise will be returned. ```javascript stmt.close(function(err) { if(err) console.log(err); }); //OR await stmt.close(); ``` ### <a name="stmtCloseSyncApi"></a> 19) (ODBCStatement) closeSync([closeOption]) Synchronously close the currently opened statement object and free resources. ```javascript stmt.closeSync(); ``` ### <a name="fetchApi"></a> 20) (ODBCResult) .fetch([option] [, callback]) Fetch a row of data from an ODBCResult object asynchronously. * **option** - _OPTIONAL_ - Object type. * fetchMode - Format of the returned row data. By default, the row data will be returned in object form. option = {fetchMode:3} or option = {fetchMode: ibmdb.FETCH_ARRAY} will return row data in array form. Default value of fetchMode is ibmdb.FETCH_OBJECT. * When option = {fetchMode : 0} or {fetchMode: ibmdb.FETCH_NODATA} is used, the fetch() API will not return any results, and the application needs to call the result.getData() or result.getDataSync() APIs to retrieve data for a column. * **callback** - _OPTIONAL_ - `callback (err, row)`. If callback is not provided, a Promise will be returned. **Note:** When `SQL_ATTR_ROW_ARRAY_SIZE` is set to a value greater than 1, `fetch()` returns an **array of rows** (up to ROW_ARRAY_SIZE rows) per call instead of a single row object. When all rows are exhausted, it returns `null`. See [Block Fetch using SQL_ATTR_ROW_ARRAY_SIZE](#block-fetch-using-sql_attr_row_array_size) for details. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err, conn){ conn.querySync("create table hits (col1 varchar(40), col2 int)"); conn.querySync("insert into hits values ('something', 42)"); conn.querySync("insert into hits values ('für', 43)"); conn.prepare("select * from hits", function (err, stmt) { if (err) { //could not prepare for some reason console.log(err); return conn.closeSync(); } stmt.execute(function (err, result) { if( err ) console.log(err); result.fetch((err, row) => { if(err) { console.log(err); } else { console.log("Row1 = ", row); result.fetch({fetchMode:ibmdb.FETCH_ARRAY}).then(row => { console.log("Row2 = ", row); result.closeSync(); conn.querySync("drop table hits"); //Close the connection conn.close(function(err){console.log("Connection Closed.");}); }).catch(err => console.log(err)); } }); }); }); }); ``` ### <a name="fetchSyncApi"></a> 21) (ODBCResult) .fetchSync([option]) Fetch a row of data from the ODBCResult object synchronously. * **option** - _OPTIONAL_ - Object type. * fetchMode - Format of the returned row data. By default, the row data will be returned in object form. option = {fetchMode:3} or option = {fetchMode: ibmdb.FETCH_ARRAY} will return row data in array form. Default value of fetchMode is ibmdb.FETCH_OBJECT. * When option = {fetchMode : 0} or {fetchMode: ibmdb.FETCH_NODATA} is used, the fetch() API will not return any results, and the application needs to call the result.getData() or result.getDataSync() APIs to retrieve data for a column. **Note:** When `SQL_ATTR_ROW_ARRAY_SIZE` is set to a value greater than 1, `fetchSync()` returns an **array of rows** (up to ROW_ARRAY_SIZE rows) per call instead of a single row object. When all rows are exhausted, it returns `null`. See [Block Fetch using SQL_ATTR_ROW_ARRAY_SIZE](#block-fetch-using-sql_attr_row_array_size) for details. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err, conn){ conn.querySync("create table hits (col1 varchar(40), col2 int)"); conn.querySync("insert into hits values ('something', 42)"); conn.querySync("insert into hits values ('für', 43)"); const stmt = conn.prepareSync("select * from hits"); const result = stmt.executeSync(); const data = 0; while( data = result.fetchSync({fetchMode:3}) ) { console.log(data); } result.closeSync(); conn.querySync("drop table hits"); conn.closeSync(); }); ``` ### <a name="fetchAllApi"></a> 22) (ODBCResult) .fetchAll([option] [, callback]) Fetch all rows from ODBCResult object asynchronously for the executed statement. * **option** - _OPTIONAL_ - Object type. * fetchMode - Format of the returned row data. By default, the row data will be returned in object form. option = {fetchMode:3} or option = {fetchMode: ibmdb.FETCH_ARRAY} will return row data in array form. Default value of fetchMode is ibmdb.FETCH_OBJECT. * **callback** - _OPTIONAL_ - `callback (err, data, noOfColumns)`. If callback is not provided, a Promise will be returned. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err, conn){ conn.querySync("create table hits (col1 varchar(40), col2 int)"); conn.querySync("insert into hits values ('something', 42)"); conn.querySync("insert into hits values ('für', 43)"); conn.prepare("select * from hits", function (err, stmt) { if (err) { //could not prepare for some reason console.log(err); return conn.closeSync(); } stmt.execute(function (err, result) { if( err ) console.log(err); result.fetchAll({fetchMode:4}, function (err, data, colcount) { if(err) { console.log(err); } else { console.log("Data = ", data); console.log("No of columns = ", colcount); } result.closeSync(); conn.querySync("drop table hits"); //Close the connection conn.close(function(err){console.log("Connection Closed.");}); }); }); }); }); ``` ### <a name="fetchAllSyncApi"></a> 23) (ODBCResult) .fetchAllSync([option]) Fetch all rows from ODBCResult object Synchronously for the executed statement. * **option** - Format of the returned row data. By default, the row data will be returned in object form. option = {fetchMode:3} or option = {fetchMode: ibmdb.FETCH_ARRAY} will return row data in array form. Default value of fetchMode is ibmdb.FETCH_OBJECT. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn,function(err, conn){ conn.querySync("create table hits (col1 varchar(40), col2 int)"); conn.querySync("insert into hits values ('something', 42)"); conn.querySync("insert into hits values ('für', 43)"); const stmt = conn.prepareSync("select * from hits"); const result = stmt.executeSync(); const data = result.fetchAllSync(); console.log("Fetched data = ", data); result.closeSync(); conn.querySync("drop table hits"); conn.closeSync(); }); ``` For example of prepare once and execute many times with above fetch APIs, please see test file [test-fetch-apis.js](https://github.com/ibmdb/node-ibm_db/blob/master/test/test-fetch-apis.js). ### <a name="fetchNApi"></a> (ODBCResult) .fetchN(count [, option] [, callback]) Fetch up to `count` rows from ODBCResult object asynchronously. Returns an array of rows. If fewer than `count` rows remain, only the available rows are returned. Returns an empty array when no more rows are available. Unlike `fetchAll()`, this method does not close the cursor or free columns after fetching, so you can call it repeatedly to process a large result set in batches. * **count** - _REQUIRED_ - Number - Maximum number of rows to fetch in this batch. Must be a positive integer. * **option** - _OPTIONAL_ - Object type. * fetchMode - Format of the returned row data. By default, the row data will be returned in object form. option = {fetchMode:3} or option = {fetchMode: ibmdb.FETCH_ARRAY} will return row data in array form. Default value of fetchMode is ibmdb.FETCH_OBJECT. * **callback** - _OPTIONAL_ - `callback (err, data)`. If callback is not provided, a Promise will be returned. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn, async function(err, conn) { conn.querySync("create table mytable (col1 varchar(40), col2 int)"); for (let i = 1; i <= 100; i++) { conn.querySync(`insert into mytable values ('row${i}', ${i})`); } const stmt = conn.prepareSync("select * from mytable"); const result = stmt.executeSync(); // Fetch rows in batches of 10 using Promises let batch; while ((batch = await result.fetchN(10)).length > 0) { console.log("Fetched batch of", batch.length, "rows"); // Process the batch... } result.closeSync(); conn.querySync("drop table mytable"); conn.close(function(err) { console.log("Connection Closed."); }); }); ``` ### <a name="fetchNSyncApi"></a> (ODBCResult) .fetchNSync(count [, option]) Fetch up to `count` rows from ODBCResult object synchronously. Returns an array of rows. If fewer than `count` rows remain, only the available rows are returned. Returns an empty array when no more rows are available. Unlike `fetchAllSync()`, this method does not close the cursor or free columns after fetching, so you can call it repeatedly to process a large result set in batches. * **count** - _REQUIRED_ - Number - Maximum number of rows to fetch in this batch. Must be a positive integer. * **option** - _OPTIONAL_ - Object type. * fetchMode - Format of the returned row data. By default, the row data will be returned in object form. option = {fetchMode:3} or option = {fetchMode: ibmdb.FETCH_ARRAY} will return row data in array form. Default value of fetchMode is ibmdb.FETCH_OBJECT. ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn, function(err, conn) { conn.querySync("create table mytable (col1 varchar(40), col2 int)"); for (let i = 1; i <= 100; i++) { conn.querySync(`insert into mytable values ('row${i}', ${i})`); } const stmt = conn.prepareSync("select * from mytable"); const result = stmt.executeSync(); // Fetch rows in batches of 25 let batch; while ((batch = result.fetchNSync(25)).length > 0) { console.log("Fetched batch of", batch.length, "rows"); // Process the batch... } result.closeSync(); conn.querySync("drop table mytable"); conn.closeSync(); }); ``` ### Block Fetch using SQL_ATTR_ROW_ARRAY_SIZE When `SQL_ATTR_ROW_ARRAY_SIZE` is set to a value greater than 1 on a prepared statement, ibm_db uses **SQLBindCol-based block fetching** to retrieve multiple rows per `SQLFetch()` call. This improves performance by reducing the number of CLI round-trips for large result sets. All fetch APIs (`fetch`, `fetchSync`, `fetchAll`, `fetchAllSync`, `fetchN`, `fetchNSync`) automatically detect and honor `SQL_ATTR_ROW_ARRAY_SIZE`. If the attribute is set to 1 (default), the normal single-row `SQLGetData` path is used. **API behavior when `SQL_ATTR_ROW_ARRAY_SIZE > 1`:** | API | Return value | |-----|-------------| | `fetchSync()` | Array of up to N row objects (or arrays if FETCH_ARRAY). Returns `null` when done. | | `fetch()` | Same as fetchSync, via callback `(err, rows)` or Promise. Returns `null` when done. | | `fetchAllSync()` | Flat array of all rows (unchanged). | | `fetchAll()` | Flat array of all rows (unchanged). | | `fetchNSync(count)` | Flat array of `count` rows (unchanged). | | `fetchN(count)` | Flat array of `count` rows (unchanged). | **Example using fetchSync with block fetch:** ```javascript const ibmdb = require("ibm_db") , cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx"; ibmdb.open(cn, function(err, conn) { conn.querySync("create table mytable (id int, name varchar(20))"); for (let i = 1; i <= 100; i++) { conn.querySync(`insert into mytable values (${i}, 'Row${i}')`); } // Set SQL_ATTR_ROW_ARRAY_SIZE to fetch 10 rows per SQLFetch() call const stmt = conn.prepareSync("select * from mytable order by id"); stmt.setAttrSync(ibmdb.SQL_ATTR_ROW_ARRAY_SIZE, 10); const result = stmt.executeSync(); // fetchSync returns an array of up to 10 rows per call let block; let totalRows = 0; while ((block = result.fetchSync()) !== null) { console.log(`Block of ${block.length} rows:`, block); totalRows += block.length; } console.log("Total fetched:", total