2009-11-05 64 views
2

这里是我的简单的PL/SQL程序:问题简单的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”存在,所以没有任何意义,程序中使用的所有表都存在。

+0

解决,谢谢! – 2009-11-05 11:20:17

+1

然后您应该发布您的答案,并且请不要编辑标题以表明问题已解决。 – 2009-11-05 11:22:28

回答

0

好了,只是为了让你知道我是如何解决这个问题(我已经解决了它的人aswered之前)。

首先,我创建了计划外的表用普通的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; 
/
+0

它的工作原理,但它仍然是错误的方法。显式游标是不必要的开销,并且循环内的COMMIT语句可能导致ORA-1002异常。当你只插入两行时,你会摆脱它,但没有更大的卷。 – APC 2009-11-07 18:59:53

+0

APC和其他海报是正确的,不太清楚为什么你会使用2个这样的游标来完成2个插入语句。如果你仍然遵循线程理查德...什么是错误的只是做:插入到ostane(SELECT typ,specifikacia_typu,spz FROM Auta WHERE substr(spz,1,2)<>'KE'AND substr(spz, 1,2)<>'KS'; ),然后重复您拥有的其他表格。任何你需要这些游标的原因? – Twelfth 2010-10-08 14:40:09

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中“随时”创建表,通常不是这样做的好主意。

从你的语法问题,托尼解释
4

除此之外,该代码应该仅仅是直的SQL插入没有任何游标。如果你确实需要一个游标,那么在使用一个明确的游标之前,尝试使用一个隐式游标。

+0

游标在那里用于SELECT查询。我已经自己解决了这个问题,我发布了工作程序。 – 2009-11-06 16:20:04