【问题标题】:plsql - dynamically change table name in cursorplsql - 动态更改游标中的表名
【发布时间】:2018-05-11 13:15:39
【问题描述】:

我在运行程序时遇到以下错误。是选择正确的.. 试图将表名作为参数传递。请帮忙。

PLS-00364:循环索引变量“CURSOR1”使用无效

  PROCEDURE generate_uniqueId(p_table_name IN VARCHAR2)  is
  --
  --
  CURSOR unique_id_cur
   IS
    SELECT /*PARALLEL(20)*/ unique_id
    FROM   p_table_name;

--
        v_file          UTL_FILE.file_type;
        V_file_name     Varchar2 (150);
    V_file_parm     Varchar2:= ora11g/test/;
    v_output    varchar2(200);


  BEGIN
         v_file_name := p_table_name || '.lst';
        v_file := UTL_FILE.fopen ('ora11g/test/', 'unique_ID_file', 'A');
        FOR cursor1 IN unique_id_cur
        LOOP
                BEGIN
                v_output := cursor1.unique_id;
                UTL_FILE.put_line (v_file, v_output);
                END;
        END LOOP;
        UTL_FILE.fflush (v_file);
        UTL_FILE.fclose (v_file);
  END generate_uniqueId ;

【问题讨论】:

  • 我认为你做不到。但这是一个很好的例子。 stackoverflow.com/a/31536690/5414063
  • 表“p_table_name”是否包含在您的数据库中,或者您通过“p_table_name”参数将表名传递给游标内的选择语句。

标签: sql oracle plsql


【解决方案1】:

您的 PL/SQL 代码有很多语法问题。

  1. 您可以在游标声明中以“from p_table_name”的形式传递表名。
CURSOR unique_id_cur
IS
SELECT /*PARALLEL(20)*/ unique_id
FROM   p_table_name;
  1. 如果你使用“VARCHAR2”数据类型那么你必须提供数据长度应该包含一个变量。此外,字符串 "ora11g/test/" 应保留在单个配额中 -'- as 'ora11g/test/'

V_file_parm Varchar2:= ora11g/test/;

  1. 您正在传递的目录,不确定它是否会接受。但是,应该使用“CREATE DIRECTORY”直接在Oracle中创建一个逻辑,然后传递在“UTL_FILE.FOPEN”中创建的新目录。

这里是创建一个可以为您编译和工作的过程的示例想法,创建如下所示的真实过程。

create or replace  PROCEDURE generate_uniqueId(p_table_name IN VARCHAR2 default 'abc')
as
CURSOR unique_id_cur
   IS
    SELECT object_id as unique_id
    FROM   all_tables
    where rownum <=5;

    v_file          UTL_FILE.file_type;
    V_file_name Varchar2(150);
    V_file_parm Varchar2(200) := 'ora11g/test/';
    v_output varchar2(200);

  BEGIN
       v_file_name := p_table_name || '.lst';
       v_file := UTL_FILE.fopen ('ora11g/test/', 'unique_ID_file', 'A');
        FOR cursor1 IN unique_id_cur
        LOOP
                BEGIN
                v_output := cursor1.unique_id;
                UTL_FILE.put_line (v_file, v_output);
                END;
        END LOOP;
        UTL_FILE.fflush (v_file);
        UTL_FILE.fclose (v_file);
  END generate_uniqueId ;

EDIT-1

create or replace  PROCEDURE generate_uniqueId(p_table_name IN VARCHAR2 default 'abc')
as
type t1 is table of varchar2(255) index by pls_integer;
v_unique_ids t1;
v_sql varchar2(4000);
    v_file          UTL_FILE.file_type;
    V_file_name Varchar2(150);
    V_file_parm Varchar2(200) := 'ora11g/test/';
    v_output varchar2(200);

  BEGIN
       v_file_name := p_table_name || '.lst';
       v_file := UTL_FILE.fopen ('ora11g/test/', 'unique_ID_file', 'A');

    v_sql := 'select /* PARALLEL(20) */ unique_id  from '|| p_table_name;
    execute immediate v_sql bulk collect into v_unique_ids;

        FOR cursor1 IN v_unique_ids.first..v_unique_ids.last
        LOOP
                BEGIN
                v_output := v_unique_ids(cursor1);
                UTL_FILE.put_line (v_file, v_output);
                END;
        END LOOP;
        UTL_FILE.fflush (v_file);
        UTL_FILE.fclose (v_file);
  END generate_uniqueId ;

【讨论】:

  • 如果你想动态改变游标的表名,那么你应该考虑“立即执行”并将输出存储到集合中。
  • 你能提供一个在光标内立即执行的例子吗?
  • ---删除游标声明unique_id_cur:---声明一个类型为“类型t1是由pls_integer索引的varchar2(255)表;” ---声明一个新类型的变量为“v_unique_ids t1;” ---声明一个变量来存储SQL为“v_sql varchar2(4000);” --- 在 Begin 中,在循环之前:“v_sql := select /* PARALLEL(20) */ unique_id bulk collect into v_unique_ids from '|| p_table_name;” --- 将 For Loop 的第一行替换为 "FOR cursor1 in v_unique_ids.first..v_unique_ids.last LOOP" --- 将第二个 BEGIN 中的行替换为将值分配给 v_ouput 为 "v_ouput := v_unique_ids(cursor1); "
  • 我是 plsql 的新手。 :S 你可以尝试在上面的代码中修改它吗?
  • 谢谢。在执行过程中出现错误:是否需要进行任何更改? ORA-00942:表或视图不存在 ORA-06512:在“sys.generate_uniqueId”,第 18 行 ORA-06512:在第 6 行
猜你喜欢
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
相关资源
最近更新 更多