使用ORACLE DB的PLSQL中的过程

时间:2012-10-31 06:45:00

标签: oracle plsql

CREATE OR REPLACE PROCEDURE ABC ( REG_NO   IN  CO_ENROLMENT.S_REGNO%TYPE,
                                  TERM     IN  COURSEOFFERING.CO_TERMNUMBER%TYPE,
                                  YEAR     IN  COURSEOFFERING.CO_YEAR%TYPE,
                                  CO_TITLE IN  COURSE.C_TITLE%TYPE,
                                  EN_DATE  OUT CO_ENROLMENT.COE_ENROLDATE%TYPE,
                                  COM_ST   OUT CO_ENROLMENT.COE_COMPLETIONSTATUS%TYPE)

AS 
BEGIN
   SELECT M.COE_COMPLETIONSTATUS, M.COE_ENROLDATE 
     INTO COM_ST, EN_DATE
     FROM COURSEOFFERING O
    INNER JOIN COURSE C
            ON C.C_ID = O.C_ID
    INNER JOIN CO_ENROLMENT M
            ON M.CO_ID = O.CO_ID
    WHERE M.S_REGNO LIKE REG_NO AND
          O.CO_TERMNUMBER LIKE TERM AND
          O.CO_YEAR LIKE YEAR AND
          C.C_TITLE LIKE CO_TITLE;
END ABC;

我已经写下了上述程序。 下面是调用上面程序的PL / SQL块,

DECLARE
  COMPL_STATUS   CO_ENROLMENT.COE_COMPLETIONSTATUS%TYPE;
  ENROL_DATE     CO_ENROLMENT.COE_ENROLDATE%TYPE;
BEGIN
  ABC (44444444, 2009, 2, 'PLSQL Programming', 
       EN_DATE => enrol_date, COM_ST =>compl_status);
  DBMS_OUTPUT.PUT_LINE ('STUDENT COMPLETION STATUS AND ENROLMENT DATE IS ' 
                         || ENROL_DATE
                         || '    ' 
                         || compl_status );
END;

它返回错误,因为没有找到数据,但是当我单独运行查询时,我得到了输出。我无法弄清楚出了什么问题。我是否正确编写了程序块,PL / SQL块中传递的参数是否正确?

4 个答案:

答案 0 :(得分:1)

在proc中你有第三名的年份但是你把它称为第二名。类型如何? (COURSEOFFERING.CO_TERMNUMBER%TYPE,COURSEOFFERING.CO_TERMNUMBER%TYPE)宣布了吗?

答案 1 :(得分:1)

select过程中的ABC语句没有返回任何行时,将引发NO_DATA_FOUND异常,并且将停止执行存储过程。要避免此类行为,您需要在存储过程中添加EXCEPTION部分以捕获异常并做出适当的反应。为此,存储过程的执行部分可能看起来:

BEGIN
   SELECT M.COE_COMPLETIONSTATUS, M.COE_ENROLDATE 
     INTO COM_ST, EN_DATE
     FROM COURSEOFFERING O
    INNER JOIN COURSE C
            ON C.C_ID = O.C_ID
    INNER JOIN CO_ENROLMENT M
            ON M.CO_ID = O.CO_ID
    WHERE M.S_REGNO LIKE REG_NO AND
          O.CO_TERMNUMBER LIKE TERM AND
          O.CO_YEAR LIKE YEAR AND
          C.C_TITLE LIKE CO_TITLE;
EXCEPTION
  WHEN NO_DATA_FOUND
  THEN DBMS_OUTPUT.PUT_LINE('No data found') -- for example
END ABC

或者如果您想继续进行即使select语句引发异常,也可以将select语句包含在嵌套BEGIN .. END块中。

BEGIN
   -- some code before
   BEGIN    
     SELECT M.COE_COMPLETIONSTATUS, M.COE_ENROLDATE 
       INTO COM_ST, EN_DATE
       FROM COURSEOFFERING O
      INNER JOIN COURSE C
              ON C.C_ID = O.C_ID
      INNER JOIN CO_ENROLMENT M
              ON M.CO_ID = O.CO_ID
      WHERE M.S_REGNO LIKE REG_NO AND
            O.CO_TERMNUMBER LIKE TERM AND
            O.CO_YEAR LIKE YEAR AND
            C.C_TITLE LIKE CO_TITLE;
   EXCEPTION
     WHEN NO_DATA_FOUND
     THEN DBMS_OUTPUT.PUT_LINE('No data found') -- for example
  END;
  -- some code after
END ABC

答案 2 :(得分:1)

您的过程查询中可能缺少通配符。

16:02:06 SYSTEM@dwh-prod> select * from dual where 'abc' like 'ab'; 

no rows selected                                                    


16:02:18 SYSTEM@dwh-prod> select * from dual where 'abc' like 'ab%';

D                                                                   
-                                                                   
X                                                                   

没有它们,C.C_TITLE LIKE CO_TITLE等于C.C_TITLE = CO_TITLE,这不是你想要的。

尝试C.C_TITLE LIKE '%'||CO_TITLE||'%'

答案 3 :(得分:0)

您正在错误地调用存储过程。您必须以正确的顺序指定参数,或使用命名参数表示法,即

ABC (44444444, 2, 2009, 'PLSQL Programming', enrol_date, compl_status);

ABC (REG_NO => 44444444, YEAR => 2009, TERM => 2,
   CO_TITLE => 'PLSQL Programming', 
   EN_DATE => enrol_date, COM_ST =>compl_status);

您可以看到,如果使用命名参数表示法,则可以按不同的顺序指定参数(如果参数具有DEFAULT值,则根本不指定)。