过程中的 PL/SQL 游标不起作用

Posted

技术标签:

【中文标题】过程中的 PL/SQL 游标不起作用【英文标题】:PL/SQL Cursor in Procedure doesn't work 【发布时间】:2016-01-26 19:41:02 【问题描述】:

好吧,我的数据库中有培训师和认证表(类似于学位或执照),我正在尝试创建程序,对于给定的培训师 ID 和新日期,该程序将更新此人的执照。

     CREATE TABLE Trainer
(
    trainer_id number(10) PRIMARY KEY,
    name varchar2(15),
    surname varchar2(15),
    address varchar2(50),
    phone number(8),
    certification number(10)
);

INSERT INTO Trainer 
  VALUES(null, 'John', 'Climps', 'Blowing St, 134',18273643, 10);
INSERT INTO Trainer 
  VALUES(null, 'Bill', 'Spark', 'Academic St, 2', 28947384, 2);
INSERT INTO Trainer 
  VALUES(null, 'Olga', 'Redric', 'Captain Jack St, 7', 11862343, 6);
INSERT INTO Trainer 
  VALUES(null, 'Alex', 'Rose', 'Green St, 98', 18238633, 4);
INSERT INTO Trainer 
  VALUES(null, 'Monna', 'Lebindsky', 'Doge St, 1', 18685663, 5);
INSERT INTO Trainer 
  VALUES(null, 'Jack', 'Not', 'Tahon St, 76', 28941643, 3);
INSERT INTO Trainer 
  VALUES(null, 'Max', 'Scheight', 'Red Forrest St, 25', 28164064, 7);
INSERT INTO Trainer 
  VALUES(null, 'Emily', 'Ruby', 'Main St, 8', 1894636474, 8);
INSERT INTO Trainer 
  VALUES(null, 'Linda', 'Glaze', 'Yelecki St, 63', 18462343, 9);
INSERT INTO Trainer 
  VALUES(null, 'Merry', 'Gold', 'Main St, 101', 18434334, 1);

DROP TABLE Certification;
CREATE TABLE Certification
(
  certific_id number(10) PRIMARY KEY,
  name varchar2(50),
  description varchar2(1000),
  date_of_achieve varchar2(8),
  date_of_expire varchar2(8)
);

INSERT INTO Certification 
  VALUES(null, 'Fitness trainer', 'Course for a  beginner fitness trainer', 
  '09.10.15', '09.10.16');
INSERT INTO Certification 
  VALUES(null, 'Fitness trainer', 'Course for a  advanced fitness trainer', 
  '17.07.13', '13.07.16');
INSERT INTO Certification 
  VALUES(null, 'Football trainer', 'Degree of a football trainer', '11.01.12', 
  '01.10.16');
INSERT INTO Certification 
  VALUES(null, 'Tennis trainer', 'Degree of a  tennis trainer', '25.05.15', 
  '12.04.18');
INSERT INTO Certification 
  VALUES(null, 'Swimming trainer', 'Course for a swimming trainer for children',
  '18.10.14', '18.10.17');
INSERT INTO Certification 
  VALUES(null, 'Yoga master', 'Achieved after special yoga and medidation 
  cources in India','01.12.13', '15.04.16');
INSERT INTO Certification 
  VALUES(null, 'Sport master', 'Specialist in all sport activities', '14.03.14', 
  '14.03.18');
INSERT INTO Certification 
  VALUES(null, 'Fitness trainer', 'Master in workouts', '11.09.15', '11.03.18');
INSERT INTO Certification 
  VALUES(null, 'Equipment specialist', 'Master and instrucor of gym equipments', 
  '30.09.12', '30.01.16');
INSERT INTO Certification 
  VALUES(null, 'Boxer', 'Master in martial arts and boxing', '27.11.13', 
  '17.12.16');

这是我的程序

 CREATE OR REPLACE PROCEDURE updateTrainerCertificate(trainerID in number, nextDate in varchar)
AS
  no_trainer exception;
  no_name exception;
  invalid_date exception;
  no_certificate exception;

  tr_id number(10);
  tr_name varchar2(50);
  certific number(10);
  new_day_achieve varchar(8);
  Begin
  SELECT trainer_id INTO tr_id FROM Trainer WHERE trainer_id = trainerID;
  if tr_id is null then raise no_trainer;
  else
    SELECT name INTO tr_name FROM Trainer WHERE trainer_id = tr_id;
    if tr_name is null then no_name;
    else
      SELECT certification INTO certific FROM Trainer, Certification
      WHERE Trainer.certification = Certification.certific_id
      AND trainer_id = tr_id;    
      if certificate in null then raise no_certificate; 
      else
       SELECT TO_CHAR(sysdate, 'DD.MM.YY') INTO new_day_achieve 
       FROM DUAL; 
        if LENGTH(new_day_achieve) != 8 or LENGTH(nextDate) != 8 
        then raise invalid_date;
        else
          UPDATE Certification SET date_of_achieve = new_date_achieve,
                                   date_of_expire = nextDate
          WHERE certific_id = certific;

          DBMS_output.put_line(tr_name || ' updated certificate from ' 
          || new_day_achive || ' till ' || nextDate); 
        end if;
      end if;
    end if;
  end if;

exception
  when no_trainer then dbms_output.put_line('No trainer found');
  when no_name then dbms_output.put_line('Error. Trainer without name. 
                                          Check table Trainer');
  when invalid_date then dbms_output.put_line('Invalid date format');
  when no_certificate then dbms_output.put_line('Trainer does not have any 
                                                certificate');
End;
/

编译显示难以理解的错误

【问题讨论】:

【参考方案1】:

创建表和插入数据的代码错误,它尝试在非空列中插入一些空值。

在程序中,变量名错误,此代码为我编译:


 CREATE OR REPLACE PROCEDURE updateTrainerCertificate(trainerID in number, nextDate in varchar)
AS
  no_trainer exception;
  no_name exception;
  invalid_date exception;
  no_certificate exception;

  tr_id number(10);
  tr_name varchar2(50);
  certific number(10);
  new_day_achieve varchar(8);
  Begin
  SELECT trainer_id INTO tr_id FROM Trainer WHERE trainer_id = trainerID;
  if tr_id is null then raise no_trainer;
  else
    SELECT name INTO tr_name FROM Trainer WHERE trainer_id = tr_id;
    if tr_name is null then raise no_name;
    else
      SELECT certification INTO certific FROM Trainer, Certification
      WHERE Trainer.certification = Certification.certific_id
      AND trainer_id = tr_id;    
      if certific is null then raise no_certificate;
      else
       SELECT TO_CHAR(sysdate, 'DD.MM.YY') INTO new_day_achieve 
       FROM DUAL; 
        if LENGTH(new_day_achieve) != 8 or LENGTH(nextDate) != 8 
        then raise invalid_date;
        else
          UPDATE Certification SET date_of_achieve = new_day_achieve,
                                   date_of_expire = nextDate
          WHERE certific_id = certific;

          DBMS_output.put_line(tr_name || ' updated certificate from ' 
          || new_day_achieve || ' till ' || nextDate); 
        end if;
      end if;
    end if;
  end if;

exception
  when no_trainer then dbms_output.put_line('No trainer found');
  when no_name then dbms_output.put_line('Error. Trainer without name. 
                                          Check table Trainer');
  when invalid_date then dbms_output.put_line('Invalid date format');
  when no_certificate then dbms_output.put_line('Trainer does not have any 
                                                certificate');
End;
/

我在 SQLDeveloper 4.0.3.16 中编译过,所有错误都在“编译器日志”窗口中可见,并指出错误所在行和原因

【讨论】:

以上是关于过程中的 PL/SQL 游标不起作用的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 语句的 SQL 查询不起作用

我的 PL/SQL 过程异常似乎不起作用

PL SQL 中的游标

条件 PL SQL 过程不起作用

从存储过程调用时,PL SQL Execute Immediate 不起作用

for循环后的最后一个过程语句在pl sql中不起作用