@@ -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 )
28128215 . [ Batch Statement Execution] ( #batchexecution )
28228316 . [ Continuous Query Notification (CQN)] ( #cqn )
28328417 . [ Transaction Management] ( #transactionmgt )
@@ -7635,6 +7636,56 @@ for really large numbers of items, you might prefer to use a global
76357636temporary table. Some solutions are given in [On Cursors, SQL, and
76367637Analytics][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
76407691The [` connection .executeMany ()` ](#executemany) method allows many sets
0 commit comments