2

这是我的简单 PL/SQL 程序:

DECLARE

    CURSOR c1 is
        SELECT typ, specifikacia_typu, spz FROM Auta
            WHERE (substr(spz, 1, 2) = 'KE' OR substr(spz, 1, 2) = 'KS') AND ROWNUM <= 2;
    CURSOR c2 is
        SELECT typ, specifikacia_typu, spz FROM Auta
            WHERE substr(spz, 1, 2) <> 'KE' AND substr(spz, 1, 2) <> 'KS';
    my_typ CHAR(10);
    my_specifikacia_typu CHAR(15);
    my_spz CHAR(8);

BEGIN

    -- vytovirt potrebne tabulky pre kosicke a nekosicke auta
    CREATE TABLE Kosicke (
    typ CHAR(10),
    specifikacia_typu CHAR(15),
    spz CHAR(8)
    );
    CREATE TABLE Ostatne (
    typ CHAR(10),
    specifikacia_typu CHAR(15),
    spz CHAR(8)
    );

    -- prve dve auta z Kosic vlozit do tabulky Kosicke
    OPEN c1;
    FOR i IN 1..2 LOOP
        FETCH c1 INTO my_typ, my_specifikacia_typu, my_spz;
        EXIT WHEN c1%NOTFOUND;
        INSERT INTO Kosice VALUES(my_typ, my_specifikacia_typu, my_spz);
        COMMIT;
    END LOOP;
    CLOSE c1;

    -- auta, ktore nie su z Kosic vlozit do tabulky Ostatne
    OPEN c2;
    LOOP
        FETCH c2 INTO my_typ, my_specifikacia_typu, my_spz;
        EXIT WHEN c2%NOTFOUND;
        INSERT INTO Ostatne VALUES(my_typ, my_specifikacia_typu, my_spz);
        COMMIT;
    END LOOP;
    CLOSE c1;

END;
/

当我运行它 Oracle 10g Express Edition 时,我收到此错误:

ORA-06550: line 16, column 5:
PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:

   begin case declare exit for goto if loop mod null pragma
   raise return select update while with 
     <<
   close current delete fetch lock insert open rollback
   savepoint set sql execute commit forall merge pipe

1. DECLARE
2.     
3.     CURSOR c1 is

我不确定问题出在哪里,这是我用 PL/SQL 编写的第一个程序,所以我有点迷茫。我使用 Oracle 网站上的这个示例程序来编写这个程序:http: //download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/a_samps.htm#563

编辑:

此外,当我先在程序外部创建表然后运行程序时,我收到此错误:

ORA-06550: line 17, column 21:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 17, column 9:
PL/SQL: SQL Statement ignored

1. DECLARE    
2.     CURSOR c1 is
3.         SELECT typ, specifikacia_typu, spz FROM Auta

这没有意义,因为表“Auta”存在,程序中使用的所有表都存在。

4

3 回答 3

4

您不能直接在 PL/SQL 中执行像 CREATE TABLE 这样的 DDL。但是,您可以使用动态 PL/SQL 来执行此操作,如下所示:

-- vytovirt potrebne tabulky pre kosicke a nekosicke auta
EXECUTE IMMEDIATE 'CREATE TABLE Kosicke (
typ CHAR(10),
specifikacia_typu CHAR(15),
spz CHAR(8)
)';

您的插入也需要是动态的,因为表在编译时不存在,因此代码无效:

EXECUTE IMMEDIATE 'INSERT INTO Ostatne VALUES(:p1, :p2, :p3)'
   USING my_typ, my_specifikacia_typu, my_spz;

不过,知道您为什么需要这样做会很有趣:几乎从不需要在 Oracle 中“即时”创建表,而且这样做通常不是一个好主意。

于 2009-11-05T11:23:57.813 回答
4

除了托尼解释过的语法问题之外,这段代码应该只是没有任何游标的直接 SQL 插入。如果你确实需要一个游标,那么在使用显式游标之前尝试使用隐式游标。

于 2009-11-05T12:19:51.990 回答
0

好的,所以只是为了让您知道我是如何解决问题的(在任何人回答之前我已经解决了)。

首先,我使用普通的 SQL 查询在程序之外创建了表:

CREATE TABLE Kosicke (
typ CHAR(10),
specifikacia_typu CHAR(15),
spz CHAR(8)
);
CREATE TABLE Ostatne (
typ CHAR(10),
specifikacia_typu CHAR(15),
spz CHAR(8)
);

我编辑了这样的程序(它已经工作了):

DECLARE

    CURSOR c1 is
        SELECT typ, specifikacia_typu, spz FROM Auta
            WHERE (substr(spz, 1, 2) = 'KE' OR substr(spz, 1, 2) = 'KS') AND ROWNUM <= 2;
    CURSOR c2 is
        SELECT typ, specifikacia_typu, spz FROM Auta
            WHERE substr(spz, 1, 2) <> 'KE' AND substr(spz, 1, 2) <> 'KS';
    my_typ CHAR(10);
    my_specifikacia_typu CHAR(15);
    my_spz CHAR(8);

BEGIN

    /* prve dve auta z Kosic vlozit do tabulky Kosicke */
    OPEN c1;
    FOR i IN 1..2 LOOP
        FETCH c1 INTO my_typ, my_specifikacia_typu, my_spz;
        EXIT WHEN c1%NOTFOUND;
        INSERT INTO Kosicke VALUES(my_typ, my_specifikacia_typu, my_spz);
        COMMIT;
    END LOOP;
    CLOSE c1;

    /* auta, ktore nie su z Kosic vlozit do tabulky Ostatne */
    OPEN c2;
    LOOP
        FETCH c2 INTO my_typ, my_specifikacia_typu, my_spz;
        EXIT WHEN c2%NOTFOUND;
        INSERT INTO Ostatne VALUES(my_typ, my_specifikacia_typu, my_spz);
        COMMIT;
    END LOOP;
    CLOSE c2;

END;
/
于 2009-11-06T15:50:24.263 回答