Skip to content

Commit e3516f2

Browse files
author
Christopher Jones
committed
Add doc on binding (or not) col & table names in queries
1 parent 01ef062 commit e3516f2

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

doc/api.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ limitations under the License.
278278
- 14.5 [LOB Bind Parameters](#lobbinds)
279279
- 14.6 [PL/SQL Collection Associative Array (Index-by) Bind Parameters](#plsqlindexbybinds)
280280
- 14.7 [Binding Multiple Values to a SQL `WHERE IN` Clause](#sqlwherein)
281+
- 14.8 [Binding Column and Table Names in Queries](#sqlbindtablename)
281282
15. [Batch Statement Execution](#batchexecution)
282283
16. [Continuous Query Notification (CQN)](#cqn)
283284
17. [Transaction Management](#transactionmgt)
@@ -7635,6 +7636,56 @@ for really large numbers of items, you might prefer to use a global
76357636
temporary table. Some solutions are given in [On Cursors, SQL, and
76367637
Analytics][59] and in [this StackOverflow answer][60].
76377638

7639+
### <a name="sqlbindtablename"></a> 14.8 Binding Column and Table Names in Queries
7640+
7641+
It is not possible to bind table names in queries. Instead use a
7642+
hardcoded whitelist of names to build the final SQL statement, for
7643+
example:
7644+
7645+
```javascript
7646+
const validTables = ['LOCATIONS', 'DEPARTMENTS'];
7647+
7648+
const tableName = getTableNameFromEndUser();
7649+
7650+
if (!validTables.includes(tableName)) {
7651+
throw new Error('Invalid table name');
7652+
}
7653+
7654+
query = 'SELECT * FROM ' + tableName;
7655+
```
7656+
7657+
The same technique can be used to construct the list of selected
7658+
column names. Make sure to use a whitelist of names to avoid SQL
7659+
Injection security risks.
7660+
7661+
Each final SQL statement will obviously be distinct, and will use a
7662+
slot in the [statement cache](#stmtcache).
7663+
7664+
It is possible to bind column names used in an ORDER BY:
7665+
7666+
```javascript
7667+
const sql = `SELECT first_name, last_name
7668+
FROM employees
7669+
ORDER BY
7670+
CASE :ob
7671+
WHEN 'FIRST_NAME' THEN first_name
7672+
ELSE last_name
7673+
END`;
7674+
7675+
const columnName = getColumnNameFromEndUser();
7676+
const binds = [columnName];
7677+
7678+
let result = await conn.execute(sql, binds);
7679+
```
7680+
7681+
In this example, when `columnName` is 'FIRST_NAME' then the result set
7682+
will be ordered by first name, otherwise the order will be by last
7683+
name.
7684+
7685+
You should analyze the statement usage patterns and optimizer query
7686+
plan before deciding whether to using binds like this, or to use
7687+
multiple hard-coded SQL statements, each with a different ORDER BY.
7688+
76387689
## <a name="batchexecution"></a> 15. Batch Statement Execution
76397690
76407691
The [`connection.executeMany()`](#executemany) method allows many sets

0 commit comments

Comments
 (0)