对于存储过程中具有表名称的循环

时间:2014-10-02 14:57:14

标签: oracle stored-procedures plsql

我正在研究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参数中传递表名。怎么做?

2 个答案:

答案 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循环,然后使用您的逻辑来确定您将执行哪个循环。