2012-09-28 69 views
3

我正在試用Pro * C代碼。我們可以在SELECT查詢中使用主機變量作爲表名嗎?

我有3個表格empmgrall;所有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; 
} 

我們可以使用SELECTFROM變量?

回答

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

2

不,我們不能使用主機變量提供一個表-name到Pro * C中的靜態SQL語句。

要爲Oracle11.2克引用Oracle Pro*C Programmer's Guide

不能使用輸入主機變量提供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 ... 

    // ... 
} 
相關問題