pl / sql过程错误问题

时间:2016-03-15 07:05:03

标签: oracle plsql

我正在尝试在pl / sql中创建一个过程,但我不能。我有2个表,一个有100个名字,另一个有100个姓。我想创建一个带有随机名称和姓氏的过程,然后我想将该数据引入另一个表中,但是我得到一个错误,我是pl / sql的新手,不知道该怎么做。这是我的代码。

DROP TABLE grade
/
CREATE TABLE grade (grade CHAR(2))
/
INSERT INTO grade VALUES ('A1');
INSERT INTO grade VALUES ('A2');
INSERT INTO grade VALUES ('A3');
INSERT INTO grade VALUES ('A4');
INSERT INTO grade VALUES ('A5');
INSERT INTO grade VALUES ('A6');
INSERT INTO grade VALUES ('A7');
INSERT INTO grade VALUES ('B1');
INSERT INTO grade VALUES ('B2');
INSERT INTO grade VALUES ('B3');
INSERT INTO grade VALUES ('B4');
INSERT INTO grade VALUES ('B5');
INSERT INTO grade VALUES ('B6');
INSERT INTO grade VALUES ('B7');
commit;

set serveroutput on
DECLARE
v_contor INTEGER := 1;
v_nr NUMBER(10);
v_name VARCHAR2(20);
v_surname VARCHAR2(20);
v_year NUMBER(2);
v_grade VARCHAR2(20);
v_scholarship NUMBER(4);
v_nota NUMBER(2);

PROCEDURE insert_data IS

cursor c1 is
   select name from(select name from name
              order by dbms_ryeardom.value)
   where rownum =1;

cursor c2 is
   select surname from(select surname from surname
              order by dbms_ryeardom.value)
   where rownum =1;

cursor c3 is 
   select grade from(select grade from grade
              order by dbms_ryeardom.value)
   where rownum =1;

BEGIN

   v_nr := 124;
   WHILE v_contor <= 2000 LOOP
        open c1;
        open c2;
    open c3;
    LOOP
        fetch c1 into v_name;
        exit when c1%notfound;
        END loop;
    LOOP
        fetch c2 into v_surname;
        exit when c2%notfound;
        END loop;
    LOOP
        fetch c3 into v_grade;
        exit when c3%notfound;
        END loop;
    v_year := round(dbms_ryeardom.value(1,3));
    v_scholarship := round(dbms_ryeardom.value(250,450));
    INSERT INTO studenti VALUES (v_nr, INITCAP(v_name), v_surname, v_year, v_grade, v_scholarship, NULL);
        IF (v_year = 2) THEN
            v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 21, v_nota, NULL);
        v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 22, v_nota, NULL);
        v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 23, v_nota, NULL);
    END if;
    IF (v_year = 3) THEN
        v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 21, v_nota, NULL);
        v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 22, v_nota, NULL);
        v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 23, v_nota, NULL);
        v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 24, v_nota, NULL);
        v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 25, v_nota, NULL);
        v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 26, v_nota, NULL);
        v_nota := round(dbms_ryeardom.value(4,10));
            INSERT INTO note VALUES (v_nr, 29, v_nota, NULL);
    END if;
        v_nr := v_nr + 1;
    v_contor := v_contor + 1;
    close c1;
    close c2;
    close c3;
    END loop;
END;
/
BEGIN
    insert_data;
END;
/

2 个答案:

答案 0 :(得分:1)

您正在PL / SQL匿名块中声明该过程而不是在SQL中 - 这不是问题,但是您正在完成过程的声明,并且没有完成匿名块的声明。

匿名PL / SQL块的格式为:

DECLARE
  ...
BEGIN
  ...
END;
/

PROCEDURE声明介于DECLAREBEGIN条款之间,其格式为:

PROCEDURE name IS ... BEGIN ... END;

在过程声明的末尾没有尾随/,因为;终止了PL / SQL语句,/用于终止最外面的PL / SQL块(表示您正在返回SQL范围 - 如果您正在嵌套PL / SQL块,那么您将不会在内部块上使用&#39; /&#39;终止符。)

如果您从代码中删除了第一个/,那么它应该摆脱end-of-file错误。

您还应该在过程中声明过程中使用的变量,而不是在包含PL / SQL匿名块(即过程的ISBEGIN子句之间,而不是外部块DECLAREPROCEDURE语句。)

如果要在SQL作用域中声明该过程(而不是在匿名块中),则需要使用:

CREATE [OR REPLACE] PROCEDURE name IS ... BEGIN ... END;
/

(在此实例中将需要尾随/,因为该语句不会包含在周围的PL / SQL匿名块中,并且将直接在SQL范围内声明,因此需要{{1表明程序的声明已经结束。)

您还有一个问题,即您的游标包含的/似乎是order by dbms_ryeardom.value的拼写错误。

重复打开和关闭相同游标也可能存在问题。

答案 1 :(得分:-1)

第一:

Create or replace procedure AS

procedure IS

第二

你无法宣布

v_contor INTEGER := 1;
v_nr NUMBER(10);
v_name VARCHAR2(20);
v_surname VARCHAR2(20);
v_year NUMBER(2);
v_grade VARCHAR2(20);
v_scholarship NUMBER(4);
v_nota NUMBER(2);

然后肌动蛋白程序。此声明必须在“AS&#39;之后”内部程序。我不记得你在程序中是否输入了有价值的长度 F.E. v_r号码;而不是v_r number(10);

尝试两种方式:)

总结summarum - 你的程序应该像这样开始

create or replace PROCEDURE insert_data AS

v_grade VARCHAR2;
v_scholarship NUMBER;
v_nota NUMBER;
....

关于结束:

END;
/
BEGIN
    insert_data;
END;
/

更改为

END;
/


BEGIN
    execute(insert_data);
END;
/