plsql游标插入到不同的模式中

时间:2017-07-17 09:34:00

标签: sql oracle plsql dynamic-sql

我有2张桌子。 第一张桌子包含许多教室的学生  (姓名,年龄,教室)

另一个表包含每个classrom(classroom,schema_name)的模式

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

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

这是我的陈述:

cd A
call mvn clean install -U
echo Completed building A
cd ..
cd B
call mvn clean install -U
echo Completed building B
cd ..
cd C
call sbt clean compile -U
echo Completed building C
cd ../
cd D
call mvn clean install -U
echo Completed building D
cd ..
cd E  
sbt clean compile
echo Completed building E

我收到此错误:

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;
/

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

2 个答案:

答案 0 :(得分:0)

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;
/

答案 1 :(得分:-1)

保存架构名称需要一个新变量。在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;
/