3

我正在试验 Pro*C 代码。

我有 3 张桌子emp, mgr, all; 所有 3 个表都包含emp_idemp_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吗?

4

2 回答 2

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

于 2012-09-28T10:00:47.563 回答
2

不,我们不能使用主机变量为 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 ...

    // ...
}
于 2013-08-11T10:46:15.207 回答