我正在尝试使用Pro * C代码。
我有3个表emp
,mgr
,all
;所有3个表格都包含emp_id
和emp_name
。我尝试了以下代码,它给了我错误。如果有可能请告诉我?
const char table_name[3]={'emp','mgr','all'}
int counter = 0;
while(counter < 3)
{
. . .
EXEC SQL SELECT emp_name INTO :ename
From :table_name[counter++]
where emp_id=:emp_id;
}
我们可以为SELECT
和FROM
使用变量吗?
答案 0 :(得分:3)
这称为动态SQL:
使用此信息:
动态SQL
虽然嵌入式SQL适用于固定应用程序,但有时程序动态创建整个SQL语句非常重要 使用动态SQL,可以发出存储在字符串变量中的语句 PREPARE将字符串转换为SQL语句,EXECUTE执行该语句。请考虑以下示例。
char *s = "INSERT INTO emp VALUES(1234, 'jon', 3)"; EXEC SQL PREPARE q FROM :s; EXEC SQL EXECUTE q;
或者,PREPARE和EXECUTE可以合并为一个语句:
char *s = "INSERT INTO emp VALUES(1234, 'jon', 3)"; EXEC SQL EXECUTE IMMEDIATE :s;
来源:http://infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html
答案 1 :(得分:2)
不,我们不能使用host-variable为Pro * C中的静态SQL语句提供表名。
为Oracle 11.2g引用Oracle Pro*C Programmer's Guide:
您不能使用输入主机变量来提供SQL关键字或数据库对象的名称。 [..]如果需要在运行时更改数据库对象名称,请使用动态SQL。另请参见第13章“Oracle Dynamic SQL”。
在Pro * C中,Oracle提供了不同的方法来执行SQL语句。主要区别在于静态和动态方法。而对于动态,有几种子方法允许不同的自由度。
静态SQL语句不是100%静态的 - 您可以在where子句表达式(作为操作数)中使用输入/输出主机变量,在insert语句中提供值,作为选择目标等。但是不要指定表名。这对于静态嵌入式SQL来说“过于动态”。
请注意,您仍然可以在动态准备的SQL语句中使用主机变量。建议这样做是为了避免SQL注入问题并提高性能(当语句执行多次时)。
示例(使用Oracle Dynamic 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 ...
// ...
}