0

我正在尝试在 PL/SQL 中对 RAISE 进行例外处理。我做了这个脚本,但是当我想运行它时,它并没有显示两条消息之一,它只是给了我“匿名块已完成”。

     Accept cititor prompt 'Introduceti un cititor'; 
      DECLARE data_la_limita EXCEPTION; data_returnare    varchar(10);
    --cititor varchar(10); 
     BEGIN 
     SELECT s.data_dereturnat INTO data_returnare FROM fisa_imprumuturi s left join legitimatii s1 
    on s1.nrlegitimatie = s.nr_legitimatie left 
   join cititori s2 on s2.codcititor = s1.codcititor 
    WHERE s2.numecititor like '%&cititor%'; IF (data_returnare > sysdate ) THEN
         RAISE data_la_limita;
   END IF; 
    EXCEPTION
          WHEN data_la_limita THEN
           DBMS_OUTPUT.PUT_LINE('Cititorul a trecut peste data returnarii!');
          WHEN OTHERS THEN
           DBMS_OUTPUT.PUT_LINE('Cititorul trebuie sa returneze la data: ' || data_returnare); END;

我尝试手动将 sysdate 替换为日期('01-May-2019'),但无法正常工作。

4

1 回答 1

2

我正在尝试在 PL / SQL 中使用 RAISE 例外...但是当我想运行它时,它不会显示两条消息之一

您没有看到这些消息,因为您在不显示 DBMS_OUTPUT 的环境中运行程序。您编写了一个 EXCEPTION 处理程序,它抑制您的异常并且不会重新引发它们。这是不好的做法,因为 DBMS_OUTPUT 不是传播异常的机制:当输出被抑制或程序作为自主后台例程运行(这是 PL/SQL 的主要用途)时,无法判断程序失败。

您可以启用 SEVEROUTPUT(在 SQL*Plus 中)或配置 DBMS_OUTPUT 选项卡(在像 SQL Developer 这样的 IDE 中)。这样做意味着您将在程序下次运行时看到这些消息。

但最好只引发异常并让调用程序处理它们。鉴于此,您可能应该像这样重新编写程序:

Accept cititor prompt 'Introduceti un cititor'; 

DECLARE 
  data_la_limita EXCEPTION; 
  data_returnare    varchar(10);
    --cititor varchar(10); 
BEGIN 

  SELECT s.data_dereturnat 
  INTO data_returnare 
  FROM fisa_imprumuturi s 
       left join legitimatii s1 on s1.nrlegitimatie = s.nr_legitimatie left 
       join cititori s2 on s2.codcititor = s1.codcititor 
    WHERE s2.numecititor like '%&cititor%'; 

  IF (data_returnare > sysdate ) THEN
         RAISE data_la_limita;
  END IF; 

EXCEPTION

  WHEN data_la_limita THEN
    raise_application_error(-20000, 'Cititorul a trecut peste data returnarii!');

END;

除非我们正在记录消息,否则最好不要编写 WHEN OTHERS 处理程序。即使这样,我们也应该执行 RAISE 来传递实际错误,而不是无用的通用消息。调用程序需要知道出了什么问题,这样它才能对下一步做什么做出正确的决定(例如忽略并继续,中止并重新引发,其他)。

于 2019-12-15T22:37:05.510 回答