不,我们不能使用主机变量为 Pro*C 中的静态 SQL 语句提供表名。
引用适用于 Oracle 11.2g的 Oracle Pro*C 程序员指南:
您不能使用输入主变量来提供 SQL 关键字或数据库对象的名称。[..] 如果您需要在运行时更改数据库对象名称,请使用动态 SQL。另请参见第 13 章,“Oracle 动态 SQL”。
在 Pro*C 中,Oracle 提供了不同的方法来执行 SQL 语句。主要区别在于静态方法和动态方法。对于动态,有几种允许不同自由度的子方法。
静态 SQL 语句不是 100% 静态的 - 您可以在 where 子句表达式(作为操作数)中使用输入/输出主机变量,在插入语句中提供值,作为选择目标等。但不能指定表名。这对于静态嵌入式 SQL 来说“过于动态”。
请注意,您仍然可以在动态准备的 SQL 语句中使用主机变量。建议这样做以避免 SQL 注入问题并提高性能(当一条语句执行多次时)。
示例(使用 Oracle 动态 SQL 方法 3):
const char *table_name[3] = {"emp", "mgr", "all"};
unsigned table_name_size = 0;
unsigned i = 0;
for (i = 0; i<table_name_size; ++i) {
char stmt[128] = {0};
snprintf(stmt, 128,
"SELECT emp_name "
" FROM %s "
" WHERE "
" emp_id = :emp_id",
table_name[i]);
EXEC SQL PREPARE emp_stmt FROM :stmt;
// check sqlca.sqlcode ...
EXEC SQL DECLARE emp_cursor CURSOR FOR emp_stmt;
EXEC SQL OPEN emp_cursor USING :emp_id;
// check sqlca.sqlcode ...
EXEC SQL FETCH emp_cursor INTO :ename;
// check sqlca.sqlcode ...
EXEC SQL CLOSE emp_cursor;
// check sqlca.sqlcode ...
// ...
}