Oracle PL/SQL中的嵌套游标

Oracle PL/SQL中的嵌套游标,oracle,plsql,cursor,nested,Oracle,Plsql,Cursor,Nested,我正在使用Oracle PL/SQL。 我试图定义嵌套游标,这意味着第一个游标的输出应该是第二个游标的输入。更具体地说:第一个应该存储带有特定前缀的表。第二个表应该存储第一个表中所有表的属性中的所有值 这是我的代码片段。我希望这能让我的问题更清楚一点: DECLARE var_table_name VARCHAR2(30); var_dimension_key VARCHAR2(30); CURSOR cur_all_dim IS SELECT

我正在使用Oracle PL/SQL。 我试图定义嵌套游标,这意味着第一个游标的输出应该是第二个游标的输入。更具体地说:第一个应该存储带有特定前缀的表。第二个表应该存储第一个表中所有表的属性中的所有值

这是我的代码片段。我希望这能让我的问题更清楚一点:

DECLARE
    var_table_name  VARCHAR2(30);
    var_dimension_key  VARCHAR2(30);

CURSOR cur_all_dim IS  
    SELECT 
        table_name
        FROM  dba_tables
        WHERE dba_tables.tablespace_name = 'USERS'
        AND dba_tables.owner = 'DWH_CORE'
        AND UPPER (dba_tables.table_name) LIKE ('%DIM%%')
        AND UPPER (dba_tables.table_name) NOT LIKE ('%TEMP%')
        AND UPPER (dba_tables.table_name) NOT LIKE ('%DEBUG%')
        AND UPPER (dba_tables.table_name) NOT LIKE ('%LOG%');

CURSOR cur_dimension_key IS
    SELECT dimension_key FROM var_table_name;


BEGIN
OPEN cur_all_dim;

LOOP
EXIT WHEN cur_all_dim%NOTFOUND;

    FETCH cur_all_dim INTO var_table_name;

    OPEN cur_dimensions_key;
    LOOP
    EXIT WHEN cur_dimensions_key%NOTFOUND;
    FETCH cur_dimensions_key INTO var_dimension_key;
    dbms_output.put_line (var_table_name);
    dbms_output.put_line (var_dimension_key);


    END LOOP;
    CLOSE cur_dimension_key;
END LOOP;
CLOSE cur_all_dim;
END;

静态游标只能访问静态对象。换句话说,静态游标只有在编译时所有表和列都已知的情况下才能工作

如果您需要访问一个只有在执行期间才知道其名称的表,则必须使用。例如,您可以在您的案例中使用:

DECLARE
   var_table_name    VARCHAR2(30);
   var_dimension_key VARCHAR2(30);
   cur_dimension_key SYS_REFCURSOR;
BEGIN
   FOR cur_all_dim IN (SELECT table_name
                         FROM dba_tables
                        WHERE dba_tables.tablespace_name = 'USERS'
                          AND dba_tables.owner = 'DWH_CORE'
                          AND UPPER(dba_tables.table_name) LIKE ('%DIM%%')
                          AND UPPER(dba_tables.table_name) NOT LIKE ('%TEMP%')
                          AND UPPER(dba_tables.table_name) NOT LIKE ('%DEBUG%')
                          AND UPPER(dba_tables.table_name) NOT LIKE ('%LOG%')) 
   LOOP      
      OPEN cur_dimension_key 
       FOR 'SELECT dimention_key 
              FROM ' || cur_all_dim.table_name;
      LOOP
         FETCH cur_dimensions_key INTO var_dimension_key;
         EXIT WHEN cur_dimensions_key%NOTFOUND;
         dbms_output.put_line(cur_all_dim.table_name);
         dbms_output.put_line(var_dimension_key);      
      END LOOP;
      CLOSE cur_dimension_key;
   END LOOP;
END;

谢谢我想我已经开始明白这是怎么回事了。但“cur_all_dim”的定义在哪里?定义已在代码中消失,但已被使用。所以我得到了一个没有声明的错误。我使用了一个。游标变量是循环的局部变量,其方式与标准过程
FOR
循环中的方式类似(您不需要在
FOR i in 1..n
中声明
i
)。好的,我理解。但是为什么我会得到一个错误“CUR\u DIMENSIONS\u KEY”没有声明?(PLS-00201)可能是因为我的代码
CUR\u DIMENSIONS\u KEY
中有一个拼写错误没有声明,但是
CUR\u DIMENSIONS\u KEY
被声明了!哦,谢谢。。我应该亲眼看看。你真的帮了我很多!
    create or replace PROCEDURE PROC_NESTED_CURSOR 
    AS 
    CUR1 SYS_REFCURSOR;
    CUR2 SYS_REFCURSOR;
    LV_DEPTID NUMBER;
    LV_DEPTNAME VARCHAR2(200);
    LV_EMPID NUMBER;
    LV_FSTNAME VARCHAR2(200);
    LV_SALARY NUMBER(8,2);
    LV_JOBID VARCHAR2(20);
    BEGIN
      OPEN CUR1 FOR 
        select department_id, department_name from departments;

      LOOP 
        FETCH CUR1 INTO LV_DEPTID,LV_DEPTNAME; 
        EXIT WHEN CUR1%NOTFOUND;    
        dbms_output.put_line('                                                                                                   ');
        dbms_output.put_line('DEPARTMENT ID  '||LV_DEPTID ||'                               '|| 'DEPARTMENT NAME  '||LV_DEPTNAME);
        dbms_output.put_line('---------------------------------------------------------------------------------------------------');
        dbms_output.put_line(RPAD('EMPLOYEE NUMBER',20)||RPAD('EMPLOYEE NAME',20) ||RPAD('SALARY',20)||RPAD('JOB',20) );
          OPEN CUR2 FOR SELECT EMPLOYEE_ID,FIRST_NAME,SALARY,JOB_ID FROM EMPLOYEES WHERE DEPARTMENT_ID = LV_DEPTID;
          LOOP 
            FETCH CUR2 INTO LV_EMPID,LV_FSTNAME,LV_SALARY,LV_JOBID;
            EXIT WHEN CUR2%NOTFOUND;
             dbms_output.put_line(RPAD( LV_EMPID,20)|| RPAD(LV_FSTNAME,20)||RPAD(LV_SALARY,20)||LV_JOBID);

            END LOOP;
       END LOOP; 
    END PROC_NESTED_CURSOR;

/**This will print like this:-
    Department Number :10               Department Name : XXXX
    ________________________________________________________
    EMPLOYEE NUMBER    EMPLOYEE NAME      SALARY         JOB

    XXXXXX                  XXXXXX                  XXXX            XXXXX
    XXXXXX                  XXXXXX                  XXXX            XXXXX
    .........

**/