plsql游标插入不同的模式

plsql cursor insert into different schemas

我有 2 个 table。 第一个 table 包含许多班级的学生 (姓名、年龄、班级)

另一个 table 包含每个课堂的模式(课堂,schema_name)

(所以每个班级都有不同的模式)

所以我对每个班级都有不同的模式。我需要从学生 table 获取所有数据并将它们复制到正确模式的目标 table 中。 (我以管理员身份登录,我可以访问所有模式)

这是我的声明:

DECLARE
   CURSOR all_pupils
   IS
      SELECT NAME, AGE, CLASSROOM FROM TABLE_1
BEGIN
   FOR pupil_rec 
   IN  all_pupils
   LOOP
       EXECUTE IMMEDIATE 'INSERT INTO ' 
           || (Select schema_name FROM TABLE_2 sn WHERE sn.classroom=pupil_rec.CLASSROOM) ||'.TARGET_TABLE ' 
         ||'(name, age) VALUES (pupil_rec.name, pupil_rec.age';
   END LOOP;
END;
/

我收到这个错误:

PLS-00103: Encountered the symbol "END" when expecting one of the following:

我刚开始学习PLSQL,有人告诉我必须用游标来做。有人可以帮助我并告诉我这是否是正确的方法吗?我的结构似乎不正确..如何避免这些错误

保存架构名称需要一个新变量。在 Execute Immediate 中不能连接其他 SELECT 除非它作为字符串提供。

DECLARE

    CURSOR all_pupils
    IS

        SELECT NAME,
            AGE,
            CLASSROOM
        FROM TABLE_1;

    v_chr_schema TABLE_2.schema_name%TYPE;
BEGIN

    FOR pupil_rec IN all_pupils
    LOOP

        SELECT schema_name
        INTO v_chr_schema
        FROM TABLE_2
        WHERE sn.classroom=pupil_rec.CLASSROOM;

        EXECUTE IMMEDIATE 'INSERT INTO ' || v_chr_schema ||'.TARGET_TABLE ' ||
        '(name, age) VALUES (' || pupil_rec.name || ',' || pupil_rec.age || ')';

    END LOOP;

END;
/

EXECUTE IMMEDIATE 仅适用于静态字符串。因此,您需要先查询模式名称,将其查询到一个变量中,然后将该变量包含在您的语句中。

而且光标的内容不会在执行字符串的范围内。所以你需要通过占位符来传递它的值。

DECLARE
    CURSOR all_pupils
    IS
        SELECT NAME, AGE, CLASSROOM FROM TABLE_1;
    l_schema_name varchar2(30);
BEGIN
   FOR pupil_rec 
   IN  all_pupils
   LOOP
       Select schema_name 
       into l_schema_name 
       FROM TABLE_2 sn 
       WHERE sn.classroom=pupil_rec.CLASSROOM:
       EXECUTE IMMEDIATE 'INSERT INTO ' 
           || l_schema_name  ||'.TARGET_TABLE ' 
           ||'(name, age) VALUES (:1, :2)'
           using pupil_rec.name, pupil_rec.age;
   END LOOP;
END;
/

或者,在驱动游标中使用连接 ...

DECLARE
    CURSOR all_pupils
    IS
        SELECT t1.NAME, t1.AGE, sn.schema_name  
        FROM TABLE_1 t1
             join TABLE_2 sn 
             on sn.classroom = T1.CLASSROOM
        where t1.col_copied != 1
        for update of t1.col_copied ;
BEGIN
   FOR pupil_rec 
   IN  all_pupils
   LOOP
       EXECUTE IMMEDIATE 'INSERT INTO ' 
           || pupil_rec.schema_name  ||'.TARGET_TABLE ' 
           ||'(name, age) VALUES (:1, :2)'
           using pupil_rec.name, pupil_rec.age;

       update  TABLE_1 t1
       set t1.col_copied = 1
       where current of all_pupils;

   END LOOP;
END;
/