我正在研究Oracle存储过程。
我的要求低于
IF variable1 := 'true"
THEN
tableName=abr
ELSE
tableName=mvr
END IF;
FOR i IN (select unique(row1) as sc from tableName t where t.row2 = 'name') LOOP
BEGIN
-- required Logic
END
END LOOP;
但是在这里我无法在tableName参数中传递表名。怎么做?
答案 0 :(得分:2)
您需要使用Execute Immediate
- 它是专为直到运行时才知道的操作而设计的。
对于正常操作,Oracle必须在编译时知道表和列。您无法执行SELECT * FROM tableName
,因为它不知道tableName是什么,因此无法正确编译。
相反,您可以执行EXECUTE IMMEDIATE 'SELECT * FROM ' || tableName;
您可以选择结果INTO
变量,将结果集或BULK COLLECT
循环到结构中,然后迭代它。
对于简单的选择,你可以这样做:
EXECUTE IMMEDIATE 'SELECT COL1, COL2 FROM ' || tableName INTO V_COL1, V_COL2
V_COL1& V_COL2只是局部变量,tableName是表示表名的字符串,COL2和COL2是您选择的表中的列。您可以使用ALL_TAB_COLUMNS之类的函数来动态获取表的结构。
以下是Oracle docs的一个示例:
CREATE OR REPLACE PROCEDURE query_invoice(
month VARCHAR2,
year VARCHAR2) IS
TYPE cur_typ IS REF CURSOR;
c cur_typ;
query_str VARCHAR2(200);
inv_num NUMBER;
inv_cust VARCHAR2(20);
inv_amt NUMBER;
BEGIN
query_str := 'SELECT num, cust, amt FROM inv_' || month ||'_'|| year
|| ' WHERE invnum = :id';
OPEN c FOR query_str USING inv_num;
LOOP
FETCH c INTO inv_num, inv_cust, inv_amt;
EXIT WHEN c%NOTFOUND;
-- process row here
END LOOP;
CLOSE c;
END;
/
http://docs.oracle.com/cd/B12037_01/appdev.101/b10795/adfns_dy.htm
答案 1 :(得分:-1)
您将不得不为每个表构建一个for循环,然后使用您的逻辑来确定您将执行哪个循环。