PL / SQL - 在for循环中使用参数

时间:2017-12-19 19:09:32

标签: oracle plsql oracle11g

我认为问题是我在定义嵌套for循环时无法调用for循环参数。附加错误。

我试图编写一个存储过程来在线重组索引表空间。我在FOR循环中使用参数时遇到问题。如何使FOR循环使用参数:

    create or replace procedure REORGANIZE_MASTER AS

      v_stmt varchar2(600);
      v_stmt2 varchar2(600);
      v_stmt3 varchar2(600);
      v_stmt4 varchar2(600);

    begin
      for i in (SELECT LTRIM(username, 'USR_') CUST_SCHEMA
                  FROM dba_users
                 WHERE username LIKE 'USR_S%')
      loop

        v_stmt:='CREATE BIGFILE TABLESPACE REB_'||i.CUST_SCHEMA;
        dbms_output.put_line(v_stmt);
        --execute immediate v_stmt;

          for i in (SELECT index_name FROM dba_indexes WHERE owner = '||i.CUST_SCHEMA||')
          loop
            v_stmt2:= 'alter i.index_name rebuild online tablespace REB_'||i.CUST_SCHEMA;
            dbms_output.put_line(v_stmt2);
            --execute immediate v_stmt2;
          end loop;

        v_stmt3:='drop tablespace IDX_'||i.CUST_SCHEMA||' including contents and datafiles;';
        dbms_output.put_line(v_stmt3);
        --execute immediate v_stmt3;

        v_stmt4:='alter tablespace REB_'||i.CUST_SCHEMA||' rename to IDX_'||i.CUST_SCHEMA;
        dbms_output.put_line(v_stmt4);
        --execute immediate v_stmt4;

      end loop;
    end;
    /

    show errors
    exit


    Errors for PROCEDURE REORGANIZE_MASTER:

    LINE/COL ERROR
    -------- -----------------------------------------------------------------
    20/17    PL/SQL: Statement ignored
    20/82    PLS-00302: component 'CUST_SCHEMA' must be declared

1 个答案:

答案 0 :(得分:3)

您正在创建两个循环,两个循环变量都称为i,其中一个嵌套在另一个循环变量中。在内环中,"外部"变量名i被赋予内部循环变量的相同名称掩盖,因此内部循环中不存在i.CUST_SCHEMA。 (它仍然存在于外部循环中 - 该错误与内部循环中使用的i.CUST_SCHEMA有关。)

你的第二个循环需要另一个循环变量名,它还需要以不同方式使用/连接两个循环中的值 - 你当前正在寻找由文字值||i.CUST_SCHEMA||拥有的索引而不是该光标字段的值:

  -- call the second loop variable j instead of i (or something more meaningful...)
  -- refer to the schema name directly, not as a text literal
  for j in (SELECT index_name FROM dba_indexes WHERE owner = i.CUST_SCHEMA)
  loop
    -- concatenate in the index name from the j loop
    -- include the 'index' keyword in the alter statement
    v_stmt2:= 'alter index ' || j.index_name
      || ' rebuild online tablespace REB_'||i.CUST_SCHEMA;
    dbms_output.put_line(v_stmt2);
    --execute immediate v_stmt2;
  end loop;