web_plsql 0.16.1 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "web_plsql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"author": "Dieter Oberkofler <dieter.oberkofler@gmail.com>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "The Express Middleware for Oracle PL/SQL",
|
|
@@ -61,30 +61,28 @@
|
|
|
61
61
|
"cookie-parser": "1.4.7",
|
|
62
62
|
"debug": "4.4.3",
|
|
63
63
|
"express": "5.2.1",
|
|
64
|
-
"fs-extra": "11.3.2",
|
|
65
64
|
"http-parser-js": "0.5.10",
|
|
66
65
|
"morgan": "1.10.1",
|
|
67
66
|
"multer": "2.0.2",
|
|
68
67
|
"rotating-file-stream": "3.2.7",
|
|
69
|
-
"zod": "4.
|
|
68
|
+
"zod": "4.3.6"
|
|
70
69
|
},
|
|
71
70
|
"devDependencies": {
|
|
72
71
|
"@types/basic-auth": "1.1.8",
|
|
73
72
|
"@types/compression": "1.8.1",
|
|
74
73
|
"@types/cookie-parser": "1.4.10",
|
|
75
74
|
"@types/debug": "4.1.12",
|
|
76
|
-
"@types/fs-extra": "11.0.4",
|
|
77
75
|
"@types/morgan": "1.9.10",
|
|
78
76
|
"@types/multer": "2.0.0",
|
|
79
|
-
"@types/node": "
|
|
80
|
-
"@types/oracledb": "6.10.
|
|
77
|
+
"@types/node": "25.0.10",
|
|
78
|
+
"@types/oracledb": "6.10.1",
|
|
81
79
|
"@types/supertest": "6.0.3",
|
|
82
|
-
"eslint": "9.39.
|
|
83
|
-
"eslint-plugin-jsdoc": "
|
|
84
|
-
"prettier": "3.
|
|
80
|
+
"eslint": "9.39.2",
|
|
81
|
+
"eslint-plugin-jsdoc": "62.4.1",
|
|
82
|
+
"prettier": "3.8.1",
|
|
85
83
|
"shx": "0.4.0",
|
|
86
|
-
"supertest": "7.
|
|
84
|
+
"supertest": "7.2.2",
|
|
87
85
|
"typescript": "5.9.3",
|
|
88
|
-
"typescript-eslint": "8.
|
|
86
|
+
"typescript-eslint": "8.53.1"
|
|
89
87
|
}
|
|
90
88
|
}
|
|
@@ -32,48 +32,6 @@ import {sanitizeProcName} from './procedureSanitize.js';
|
|
|
32
32
|
* @typedef {import('../../types.js').BindParameterConfig} BindParameterConfig
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
|
-
/**
|
|
36
|
-
* Get the SQL statement to execute when a new procedure is invoked
|
|
37
|
-
*
|
|
38
|
-
* NOTE:
|
|
39
|
-
* 1) dbms_session.modify_package_state(dbms_session.reinitialize) is used to ensure a stateless environment by resetting package state (dbms_session.reset_package)
|
|
40
|
-
*
|
|
41
|
-
* @param {string} procedure - The procedure
|
|
42
|
-
* @returns {string} - The SQL statement to execute
|
|
43
|
-
*/
|
|
44
|
-
const getProcedureSQL = (procedure) => `
|
|
45
|
-
DECLARE
|
|
46
|
-
l_file_type VARCHAR2(32767);
|
|
47
|
-
l_file_size INTEGER;
|
|
48
|
-
l_file_exists INTEGER := 0;
|
|
49
|
-
BEGIN
|
|
50
|
-
dbms_session.modify_package_state(dbms_session.reinitialize);
|
|
51
|
-
owa.init_cgi_env(:cgicount, :cginames, :cgivalues);
|
|
52
|
-
htp.init;
|
|
53
|
-
htp.HTBUF_LEN := :htbuflen;
|
|
54
|
-
|
|
55
|
-
BEGIN
|
|
56
|
-
${procedure}
|
|
57
|
-
EXCEPTION WHEN OTHERS THEN
|
|
58
|
-
raise_application_error(-20000, 'Error executing "${procedure}"', TRUE);
|
|
59
|
-
END;
|
|
60
|
-
|
|
61
|
-
IF (wpg_docload.is_file_download()) THEN
|
|
62
|
-
wpg_docload.get_download_file(l_file_type);
|
|
63
|
-
IF (l_file_type = 'B') THEN
|
|
64
|
-
l_file_exists := 1;
|
|
65
|
-
wpg_docload.get_download_blob(:fileBlob);
|
|
66
|
-
l_file_size := dbms_lob.getlength(:fileBlob);
|
|
67
|
-
END IF;
|
|
68
|
-
END IF;
|
|
69
|
-
:fileExist := l_file_exists;
|
|
70
|
-
:fileType := l_file_type;
|
|
71
|
-
:fileSize := l_file_size;
|
|
72
|
-
|
|
73
|
-
owa.get_page(thepage=>:lines, irows=>:irows);
|
|
74
|
-
END;
|
|
75
|
-
`;
|
|
76
|
-
|
|
77
35
|
/**
|
|
78
36
|
* Get the procedure and arguments to execute
|
|
79
37
|
* @param {Request} req - The req object represents the HTTP request. (only used for debugging)
|
|
@@ -85,10 +43,10 @@ END;
|
|
|
85
43
|
*/
|
|
86
44
|
const getProcedure = async (req, procName, argObj, options, databaseConnection) => {
|
|
87
45
|
// path alias
|
|
88
|
-
if (options.pathAlias
|
|
46
|
+
if (options.pathAlias?.toLowerCase() === procName.toLowerCase()) {
|
|
89
47
|
debug(`getProcedure: path alias "${options.pathAlias}" redirects to "${options.pathAliasProcedure}"`);
|
|
90
48
|
return {
|
|
91
|
-
sql: `${options.pathAliasProcedure}(p_path=>:p_path)
|
|
49
|
+
sql: `${options.pathAliasProcedure}(p_path=>:p_path)`,
|
|
92
50
|
bind: {
|
|
93
51
|
p_path: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: procName},
|
|
94
52
|
},
|
|
@@ -109,6 +67,159 @@ const getProcedure = async (req, procName, argObj, options, databaseConnection)
|
|
|
109
67
|
}
|
|
110
68
|
};
|
|
111
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Prepare procedure
|
|
72
|
+
*
|
|
73
|
+
* NOTE:
|
|
74
|
+
* 1) dbms_session.modify_package_state(dbms_session.reinitialize) is used to ensure a stateless environment by resetting package state (dbms_session.reset_package)
|
|
75
|
+
*
|
|
76
|
+
* @param {environmentType} cgiObj - The cgi of the procedure to invoke.
|
|
77
|
+
* @param {Connection} databaseConnection - Database connection.
|
|
78
|
+
* @returns {Promise<void>} Promise resolving to void.
|
|
79
|
+
*/
|
|
80
|
+
const procedurePrepare = async (cgiObj, databaseConnection) => {
|
|
81
|
+
let sqlStatement = 'BEGIN dbms_session.modify_package_state(dbms_session.reinitialize); END;';
|
|
82
|
+
try {
|
|
83
|
+
await databaseConnection.execute(sqlStatement);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
throw new ProcedureError(`Error when preparing procedure\n${errorToString(err)}`, cgiObj, sqlStatement, {});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// htbuf_len: reduce this limit based on your worst-case character size.
|
|
89
|
+
// For most character sets, this will be 2 bytes per character, so the limit would be 127.
|
|
90
|
+
// For UTF8 Unicode, it's 3 bytes per character, meaning the limit should be 85.
|
|
91
|
+
// For the newer AL32UTF8 Unicode, it's 4 bytes per character, and the limit should be 63.
|
|
92
|
+
sqlStatement = 'BEGIN owa.init_cgi_env(:cgicount, :cginames, :cgivalues); htp.init; htp.htbuf_len := 63; END;';
|
|
93
|
+
/** @type {BindParameterConfig} */
|
|
94
|
+
const bindParameter = {
|
|
95
|
+
cgicount: {dir: oracledb.BIND_IN, type: oracledb.NUMBER, val: Object.keys(cgiObj).length},
|
|
96
|
+
cginames: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: Object.keys(cgiObj)},
|
|
97
|
+
cgivalues: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: Object.values(cgiObj)},
|
|
98
|
+
};
|
|
99
|
+
try {
|
|
100
|
+
await databaseConnection.execute(sqlStatement, bindParameter);
|
|
101
|
+
} catch (err) {
|
|
102
|
+
throw new ProcedureError(`Error when preparing procedure\n${errorToString(err)}`, cgiObj, sqlStatement, bindParameter);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Execute procedure
|
|
108
|
+
*
|
|
109
|
+
* @param {{sql: string; bind: BindParameterConfig}} para - The statement and binding to use when executing the procedure.
|
|
110
|
+
* @param {Connection} databaseConnection - Database connection.
|
|
111
|
+
* @returns {Promise<void>} Promise resolving to void.
|
|
112
|
+
*/
|
|
113
|
+
const procedureExecute = async (para, databaseConnection) => {
|
|
114
|
+
const sqlStatement = `BEGIN ${para.sql}; END;`;
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
await databaseConnection.execute(sqlStatement, para.bind);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
throw new ProcedureError(`Error when executing procedure:\n${sqlStatement}\n${errorToString(err)}`, {}, para.sql, para.bind);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Get page from procedure
|
|
125
|
+
*
|
|
126
|
+
* @param {boolean} test - Test.
|
|
127
|
+
* @param {Connection} databaseConnection - Database connection.
|
|
128
|
+
* @returns {Promise<string>} Promise resolving to the returned page content.
|
|
129
|
+
*/
|
|
130
|
+
const procedureGetPage = async (test, databaseConnection) => {
|
|
131
|
+
const MAX_IROWS = 100000;
|
|
132
|
+
|
|
133
|
+
/** @type {BindParameterConfig} */
|
|
134
|
+
const bindParameter = {
|
|
135
|
+
lines: {dir: oracledb.BIND_OUT, type: oracledb.STRING, maxArraySize: MAX_IROWS},
|
|
136
|
+
irows: {dir: oracledb.BIND_INOUT, type: oracledb.NUMBER, val: MAX_IROWS},
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const sqlStatement = 'BEGIN owa.get_page(thepage=>:lines, irows=>:irows); END;';
|
|
140
|
+
|
|
141
|
+
/** @type {Result} */
|
|
142
|
+
let result = {};
|
|
143
|
+
try {
|
|
144
|
+
result = await databaseConnection.execute(sqlStatement, bindParameter);
|
|
145
|
+
} catch (err) {
|
|
146
|
+
if (debug.enabled) {
|
|
147
|
+
debug(getBlock('results', inspect(result)));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
throw new ProcedureError(`Error when getting page returned by procedure\n${errorToString(err)}`, {}, sqlStatement, bindParameter);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const {lines, irows} = z.object({irows: z.number(), lines: z.array(z.string())}).parse(result.outBinds);
|
|
154
|
+
|
|
155
|
+
// Make sure that we have retrieved all the rows
|
|
156
|
+
if (irows > MAX_IROWS) {
|
|
157
|
+
/* istanbul ignore next */
|
|
158
|
+
throw new ProcedureError(`Error when retrieving rows. irows="${irows}"`, {}, sqlStatement, bindParameter);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return lines.join('');
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Download files from procedure
|
|
166
|
+
*
|
|
167
|
+
* @param {oracledb.Lob} fileBlob - The blob eventually containing the file.
|
|
168
|
+
* @param {Connection} databaseConnection - Database connection.
|
|
169
|
+
* @returns {Promise<{fileType: string, fileSize: number, fileBlob: stream.Readable | null}>} Promise resolving to the result.
|
|
170
|
+
*/
|
|
171
|
+
const procedureDownloadFiles = async (fileBlob, databaseConnection) => {
|
|
172
|
+
/** @type {BindParameterConfig} */
|
|
173
|
+
const bindParameter = {
|
|
174
|
+
fileType: {dir: oracledb.BIND_OUT, type: oracledb.STRING},
|
|
175
|
+
fileSize: {dir: oracledb.BIND_OUT, type: oracledb.NUMBER},
|
|
176
|
+
fileBlob: {dir: oracledb.BIND_INOUT, type: oracledb.BLOB, val: fileBlob},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const sqlStatement = `
|
|
180
|
+
DECLARE
|
|
181
|
+
l_file_type VARCHAR2(32767) := '';
|
|
182
|
+
l_file_size INTEGER := 0;
|
|
183
|
+
BEGIN
|
|
184
|
+
IF (wpg_docload.is_file_download()) THEN
|
|
185
|
+
wpg_docload.get_download_file(l_file_type);
|
|
186
|
+
IF (l_file_type = 'B') THEN
|
|
187
|
+
wpg_docload.get_download_blob(:fileBlob);
|
|
188
|
+
l_file_size := dbms_lob.getlength(:fileBlob);
|
|
189
|
+
END IF;
|
|
190
|
+
END IF;
|
|
191
|
+
:fileType := l_file_type;
|
|
192
|
+
:fileSize := l_file_size;
|
|
193
|
+
END;
|
|
194
|
+
`;
|
|
195
|
+
|
|
196
|
+
/** @type {Result | null} */
|
|
197
|
+
let result = null;
|
|
198
|
+
try {
|
|
199
|
+
result = await databaseConnection.execute(sqlStatement, bindParameter);
|
|
200
|
+
} catch (err) {
|
|
201
|
+
if (debug.enabled) {
|
|
202
|
+
debug(getBlock('results', inspect(result)));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
throw new ProcedureError(`Error when downloading files of procedure\n${errorToString(err)}`, {}, sqlStatement, bindParameter);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return z
|
|
209
|
+
.object({
|
|
210
|
+
fileType: z
|
|
211
|
+
.string()
|
|
212
|
+
.nullable()
|
|
213
|
+
.transform((val) => val ?? ''),
|
|
214
|
+
fileSize: z
|
|
215
|
+
.number()
|
|
216
|
+
.nullable()
|
|
217
|
+
.transform((val) => val ?? 0),
|
|
218
|
+
fileBlob: z.instanceof(stream.Readable).nullable(),
|
|
219
|
+
})
|
|
220
|
+
.parse(result.outBinds);
|
|
221
|
+
};
|
|
222
|
+
|
|
112
223
|
/**
|
|
113
224
|
* Invoke the Oracle procedure and return the page content
|
|
114
225
|
*
|
|
@@ -124,10 +235,8 @@ const getProcedure = async (req, procName, argObj, options, databaseConnection)
|
|
|
124
235
|
export const invokeProcedure = async (req, res, argObj, cgiObj, filesToUpload, options, databaseConnection) => {
|
|
125
236
|
debug('invokeProcedure: ENTER');
|
|
126
237
|
|
|
127
|
-
const procName = req.params.name;
|
|
128
|
-
|
|
129
238
|
//
|
|
130
|
-
//
|
|
239
|
+
// UPLOAD FILES
|
|
131
240
|
//
|
|
132
241
|
|
|
133
242
|
debug(`invokeProcedure: upload "${filesToUpload.length}" files`);
|
|
@@ -142,119 +251,67 @@ export const invokeProcedure = async (req, res, argObj, cgiObj, filesToUpload, o
|
|
|
142
251
|
}
|
|
143
252
|
|
|
144
253
|
//
|
|
145
|
-
//
|
|
254
|
+
// GET SQL STATEMENT AND ARGUMENTS
|
|
146
255
|
//
|
|
147
256
|
|
|
148
|
-
const para = await getProcedure(req,
|
|
257
|
+
const para = await getProcedure(req, req.params.name, argObj, options, databaseConnection);
|
|
149
258
|
|
|
150
259
|
//
|
|
151
|
-
//
|
|
260
|
+
// PROCEDURE PREPARE
|
|
152
261
|
//
|
|
153
262
|
|
|
154
|
-
|
|
155
|
-
const MAX_IROWS = 100000;
|
|
263
|
+
await procedurePrepare(cgiObj, databaseConnection);
|
|
156
264
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
};
|
|
265
|
+
//
|
|
266
|
+
// PROCEDURE EXECUTE
|
|
267
|
+
//
|
|
161
268
|
|
|
162
|
-
|
|
269
|
+
await procedureExecute(para, databaseConnection);
|
|
163
270
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
cginames: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: cgi.keys},
|
|
168
|
-
cgivalues: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: cgi.values},
|
|
169
|
-
htbuflen: {dir: oracledb.BIND_IN, type: oracledb.NUMBER, val: HTBUF_LEN},
|
|
170
|
-
fileExist: {dir: oracledb.BIND_OUT, type: oracledb.NUMBER},
|
|
171
|
-
fileType: {dir: oracledb.BIND_OUT, type: oracledb.STRING},
|
|
172
|
-
fileSize: {dir: oracledb.BIND_OUT, type: oracledb.NUMBER},
|
|
173
|
-
fileBlob: {dir: oracledb.BIND_INOUT, type: oracledb.BLOB, val: fileBlob},
|
|
174
|
-
lines: {dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: HTBUF_LEN * 2, maxArraySize: MAX_IROWS},
|
|
175
|
-
irows: {dir: oracledb.BIND_INOUT, type: oracledb.NUMBER, val: MAX_IROWS},
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
// execute procedure and retrieve page
|
|
179
|
-
const sqlStatement = getProcedureSQL(para.sql);
|
|
180
|
-
/** @type {Result | null} */
|
|
181
|
-
let result = null;
|
|
182
|
-
const bindParams = Object.assign({}, bind, para.bind);
|
|
183
|
-
try {
|
|
184
|
-
if (debug.enabled) {
|
|
185
|
-
if (debug.enabled) {
|
|
186
|
-
debug(getBlock('execute', sqlStatement));
|
|
187
|
-
// NOTE: Because inspecting a BLOB value generates a craxy amount of text, we somply remove it.
|
|
188
|
-
const temp = Object.assign({}, bindParams);
|
|
189
|
-
delete temp.fileBlob.val;
|
|
190
|
-
debug(getBlock('bindParams', inspect(temp)));
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
result = await databaseConnection.execute(sqlStatement, bindParams);
|
|
194
|
-
} catch (err) {
|
|
195
|
-
if (debug.enabled) {
|
|
196
|
-
debug(getBlock('results', inspect(result)));
|
|
197
|
-
}
|
|
271
|
+
//
|
|
272
|
+
// PROCEDURE GET PAGE
|
|
273
|
+
//
|
|
198
274
|
|
|
199
|
-
|
|
275
|
+
const lines = await procedureGetPage(true, databaseConnection);
|
|
276
|
+
if (debug.enabled) {
|
|
277
|
+
debug(getBlock('data', lines));
|
|
200
278
|
}
|
|
201
279
|
|
|
202
280
|
//
|
|
203
|
-
//
|
|
281
|
+
// PROCEDURE DOWNLOAD FILE
|
|
204
282
|
//
|
|
205
283
|
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
.object({
|
|
209
|
-
irows: z.number(),
|
|
210
|
-
lines: z.array(z.string()),
|
|
211
|
-
fileExist: z.number(),
|
|
212
|
-
fileType: z.string().nullable(),
|
|
213
|
-
fileSize: z.number().nullable(),
|
|
214
|
-
fileBlob: z.instanceof(stream.Readable).nullable(),
|
|
215
|
-
})
|
|
216
|
-
.parse(result.outBinds);
|
|
217
|
-
|
|
284
|
+
const fileBlob = await databaseConnection.createLob(oracledb.BLOB);
|
|
285
|
+
const fileDownload = await procedureDownloadFiles(fileBlob, databaseConnection);
|
|
218
286
|
if (debug.enabled) {
|
|
219
|
-
debug(getBlock('data', inspect(
|
|
287
|
+
debug(getBlock('data', inspect(fileDownload)));
|
|
220
288
|
}
|
|
221
289
|
|
|
222
|
-
// Make sure that we have retrieved all the rows
|
|
223
|
-
if (data.irows > MAX_IROWS) {
|
|
224
|
-
/* istanbul ignore next */
|
|
225
|
-
throw new ProcedureError(`Error when retrieving rows. irows="${data.irows}"`, cgiObj, para.sql, para.bind);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// combine page
|
|
229
|
-
const pageContent = data.lines.join('');
|
|
230
|
-
|
|
231
290
|
//
|
|
232
|
-
//
|
|
291
|
+
// PARSE PAGE
|
|
233
292
|
//
|
|
234
293
|
|
|
235
294
|
// parse what we received from PL/SQL
|
|
236
|
-
const pageComponents = parsePage(
|
|
295
|
+
const pageComponents = parsePage(lines);
|
|
237
296
|
|
|
238
297
|
// add "Server" header
|
|
239
298
|
pageComponents.head.server = cgiObj.SERVER_SOFTWARE;
|
|
240
299
|
|
|
241
300
|
// add file download information
|
|
242
|
-
if (
|
|
243
|
-
pageComponents.file.fileType =
|
|
244
|
-
pageComponents.file.fileSize =
|
|
245
|
-
|
|
246
|
-
pageComponents.file.fileBlob = await streamToBuffer(data.fileBlob);
|
|
247
|
-
}
|
|
301
|
+
if (fileDownload.fileType !== '' && fileDownload.fileSize > 0 && fileDownload.fileBlob !== null) {
|
|
302
|
+
pageComponents.file.fileType = fileDownload.fileType;
|
|
303
|
+
pageComponents.file.fileSize = fileDownload.fileSize;
|
|
304
|
+
pageComponents.file.fileBlob = await streamToBuffer(fileDownload.fileBlob);
|
|
248
305
|
}
|
|
249
306
|
|
|
250
307
|
//
|
|
251
|
-
//
|
|
308
|
+
// SEND THE RESPONSE
|
|
252
309
|
//
|
|
253
310
|
|
|
254
311
|
sendResponse(req, res, pageComponents);
|
|
255
312
|
|
|
256
313
|
//
|
|
257
|
-
//
|
|
314
|
+
// CLEANUP
|
|
258
315
|
//
|
|
259
316
|
|
|
260
317
|
fileBlob.destroy();
|
|
@@ -291,7 +291,7 @@ export const getProcedureNamed = async (req, procName, argObj, databaseConnectio
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
// select statement
|
|
294
|
-
const sql = `${procName}(${sqlParameter.join(', ')})
|
|
294
|
+
const sql = `${procName}(${sqlParameter.join(', ')})`;
|
|
295
295
|
|
|
296
296
|
if (debug.enabled) {
|
|
297
297
|
debug(sql);
|
|
@@ -45,7 +45,7 @@ export const getProcedureVariable = (req, procName, argObj) => {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
return {
|
|
48
|
-
sql: `${procName}(:argnames, :argvalues)
|
|
48
|
+
sql: `${procName}(:argnames, :argvalues)`,
|
|
49
49
|
bind: {
|
|
50
50
|
argnames: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: names},
|
|
51
51
|
argvalues: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: values},
|
package/src/server/version.js
CHANGED