2014-10-10 91 views
-1

我一直坚持这个事情几天了。请帮忙。甲骨文功能和触发问题

我具有限定狩猎季节数据库表:

create table season(
    season   varchar2(6) not null, 
    start_date  date not null, 
    end_date  date not null, 
    constraint pk_season primary key (season) 
); 

有一个外部程序,允许最终用户在该数据库中更新的值。但是,此外部程序在更新'start_date'或'end_date'列时不会对日期格式进行任何检查。为了解决这个问题,我尝试创建一个触发器来接受输入,并应用Oracle的TO_DATE函数。

此前的扳机,我创建了两个函数来验证两件事情:1)输入的日期是MM/DD/YYYY格式和2),以确保end_datestart_date后。

我不能让这些功能正常工作。我可能在这里有语法错误,因为我真的很熟悉使用Oracle中的触发器和函数。下面是我有:

create or replace function isValidDate(input_date in varchar2) return boolean 
is 
v_date date; 
v_diff number; 
begin 
    select to_date(input_date, 'MM/DD/YYYY') into v_date from dual; 
     return true; 
    exception when others then 
     return false; 
end; 
end isValidDate; 
/
create or replace function isValidDateRange(in_start in varchar2, in_end in varchar2) return  boolean 
is 
v_diff number; 
begin 
    select to_date(in_end, 'MM/DD/YYYY') - to_date(in_start, 'MM/DD/YYYY') into v_diff from dual; 
     if v_diff >= 0 
      return true; 
     else 
      return false; 
     end if; 
end; 
end isValidDateRange; 
/
create trigger date_format 
before insert or update on season 
for each row 
begin 
    if isValidDate(:NEW.start_date) then 
     if isValidDateRange(:NEW.start_date, :NEW.end_date) then 
      :NEW.start_date := TO_DATE(:NEW.start_date, 'MM/DD/YYYY'); 
     else 
      raise_application_error(-20100, 'End date must be AFTER Start date'); 
     end if; 
    else 
     raise_application_error(-20099, 'Date must be in MM/DD/YYYY format'); 
    end if; 
    if isValidDate(:NEW.end_date) then 
     if isValidDateRange(:NEW.start_date, :NEW.end_date) then 
      :NEW.end_date := TO_DATE(:NEW.end_date, 'MM/DD/YYYY'); 
     else 
      raise_application_error(-20100, 'End date must be AFTER Start date'); 
     end if; 
    else 
     raise_application_error(-20099, 'Date must be in MM/DD/YYYY format'); 
    end if; 
end; 
end date_format; 
/

当我尝试任何这些单独,我得到Warning: Function created with compilation errors.当我做SHOW ERRORS,它告诉我PLS-00103: Encountered the symbol "END"。我无法弄清楚我的生活发生了什么。我做这一切都错了,还是我在这里错过简单的东西?

+0

打开SQL * Plus并编译它们。复制粘贴编译时错误堆栈。它会有错误的详细信息。 – 2014-10-11 00:11:55

+0

'start_date'和'end_date'已被定义为'date',所以在触发器“看到”它们时,它们已经被转换为'date'。没有很好的理由在这个时候调用'isValidDate',尤其是因为日期将在过程中使用隐式日期格式转换回'varchar2'。触发器的唯一剩余功能是检查“end_date”是否大于或等于'start_date'。有没有一个很好的理由,你为什么不用检查约束来做呢?如果您选择使用触发器,则不需要'to_date'或'select'。 – 2014-10-11 02:19:18

回答

0

从两个函数和触发器中删除end;end <object name>;服务相同的目的。

大多数工具会自动将光标移动到适当的位置。或者您可以使用如下查询手动查找错误行号:select * from user_errors where name = 'ISVALIDDATE';