无法弄清楚为什么这个包裹代码会抛出pls-00201标识符'数据类型'必须声明错误。如果你能搞清楚,请发帖

时间:2016-04-18 13:38:21

标签: oracle package

CREATE OR REPLACE PACKAGE useful_pk
  IS
--
-- To modify this template, edit file PKGSPEC.TXT in TEMPLATE
-- directory of SQL Navigator
--
-- Purpose: Briefly explain the functionality of the package
--
-- MODIFICATION HISTORY
-- Person      Date    Comments
-- ---------   ------  ------------------------------------------
   -- Enter package declarations as shown below

   variable_name   datatype;

   PROCEDURE procedure_name
     ( param1 IN datatype DEFAULT default_value,
       param2 IN OUT datatype);

   FUNCTION function_name
     ( param1 IN datatype DEFAULT default_value,
       param2 IN OUT datatype)
     RETURN  datatype;

END; -- Package spec
/
CREATE OR REPLACE PACKAGE BODY "USEFUL_PK" AS
/******************************************************************************
   NAME:       WW_JMESA.useful_pk
   PURPOSE:

   REVISIONS:
   Ver        Date        Author           Description
   ---------  ----------  ---------------  ------------------------------------
   1.0        2/10/2009             1. Created this package body.
******************************************************************************/
/*****************************************************************************/
function fn_end_month(in_month in varchar2,in_year varchar2 )  return date
is
 tmp_date date;
 wrong_date EXCEPTION;

PRAGMA EXCEPTION_INIT(wrong_date,-01847);

PRAGMA EXCEPTION_INIT(wrong_date,-01839);

begin

if nvl(substr(in_month,1,2),'00') ='00' or  nvl(substr(in_year,1,4),'0000')='0000' then
return null;
else
tmp_date:= to_date(substr(in_month,1,2)||'/'||substr(in_month,3,2) ||'/'||substr(in_year,1,4) ,'mm/dd/yyyy');
   return tmp_date;
end if;
 EXCEPTION
   WHEN wrong_date THEN
      tmp_date:= last_day(to_date(substr(in_month,1,2)||'/01/'||substr(in_year,1,4),'mm/dd/yyyy')) ;
      return tmp_date;

    WHEN OTHERS
     THEN
     RETURN tmp_date;
end fn_end_month;

function fn_end_month(in_month in varchar2 )  return date
is
 tmp_date date;
 wrong_date EXCEPTION;

PRAGMA EXCEPTION_INIT(wrong_date,-01847);

PRAGMA EXCEPTION_INIT(wrong_date,-01839);


begin


if nvl(substr(in_month,1,4),'0000') ='0000' or  nvl(substr(in_month,5,2),'00')='00' then
return null;
else
tmp_date:= to_date(substr(in_month,5,2)||'/'||substr(in_month,7,2) ||'/'||substr(in_month,1,4) ,'mm/dd/yyyy');
   return tmp_date;
end if;
 EXCEPTION
   WHEN wrong_date  THEN
      tmp_date:= last_day(to_date(substr(in_month,5,2)||'/01/'||substr(in_month,1,4),'mm/dd/yyyy')) ;
      return tmp_date;

    WHEN OTHERS
     THEN
     RETURN tmp_date;
end fn_end_month;


END useful_pk;
/

1 个答案:

答案 0 :(得分:0)

您已从代码模板更改了包体,以将datatype等占位符替换为实际有效数据类型,并且您已替换了函数名称。包名本身有点无用,但如果其他人已经从模板中创建了一个真正的问题,那么这个问题只会出现真正的问题。

您还没有做的是更改包规范以匹配对正文的更改:

CREATE OR REPLACE PACKAGE useful_pk
  IS
--
-- To modify this template, edit file PKGSPEC.TXT in TEMPLATE
-- directory of SQL Navigator
--
-- Purpose: Briefly explain the functionality of the package
--
-- MODIFICATION HISTORY
-- Person      Date    Comments
-- ---------   ------  ------------------------------------------

  function fn_end_month(in_month in varchar2,in_year varchar2 ) return date;

  function fn_end_month(in_month in varchar2 )  return date;

END; -- Package spec
/

您必须在规范中声明的两个版本的重载fn_end_month函数才能从包外部调用它们。并且您不希望从模板中保留过程和函数,部分原因是它们没有有效的数据类型,但主要是因为如果它们在规范中,那么它们也必须身体。

你的pragma不会做你想象的那么多; from the docs

  

如果两个EXCEPTION_INIT编译指示将不同的错误代码分配给同一个用户定义的异常,则后一个编译指示将覆盖先前的编译指示。

因此第二个pragma优先,ORA-01847 将被wrong_date异常处理程序捕获。要捕获两者,您需要定义两个异常并为每个异常添加编译指示,因此每个异常都会获得不同的错误代码。

使用then others捕获所有其他异常也是一个非常糟糕的主意。您将看到返回的空值(因为tmp_date将不会被抛出异常的语句设置),并且没有指示所提供的值无效的原因。