代码之家  ›  专栏  ›  技术社区  ›  Richard Knop

简单的pl/sql程序有问题

  •  2
  • Richard Knop  · 技术社区  · 15 年前

    下面是我的简单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”存在,程序中使用的所有表都存在。

    3 回复  |  直到 12 年前
        1
  •  4
  •   Tony Andrews    15 年前

    不能在pl/sql中直接执行类似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中几乎没有任何“即时”创建表的需要,而且这样做通常不是一个好主意。

        2
  •  4
  •   David Aldridge    15 年前

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

        3
  •  0
  •   Richard Knop    15 年前

    好的,那么就让你知道我是如何解决这个问题的(我在别人问我之前就已经解决了)。

    首先,我使用普通的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;
    /