错误:数字或值错误

时间:2013-12-30 17:00:01

标签: sql oracle

我知道之前已经解决了这个错误问题,但我似乎无法找到任何相关的解决方案,所以我发布了这个问题。

create table subscribers(
  num_s  number(6,0) ,  
  name varchar2(30)  constraint nameM not null, 
  surname varchar2(20), 
  town varchar2(30), 
  age number(3,0)  ,
  rate number(3,0) ,
  reduc number(3,0) ,
  CONSTRAINT subscriber_pk primary key (num_s),
  constraint age_c check (age between 0 and 120)
);

create or replace type copy_bookT as object(
  num               number(6),
  loancode          varchar2 (10),
  book_ref          ref bookT
);

create table copy_books of copy_bookT(
  constraint pk_cb primary key (num),
  constraint chk_st check (loancode in('Loan', 'Not')),
  loancode default 'Loan' not null
);


create table Lending(
  cb_num      number(6),
  sb_num      number(6),
  date_L      date,
  constraint fk_cb foreign key (cb_num) references copy_books(num),
  constraint fk_sb foreign key (sb_num) references Subscribers(num_s)
);



create or replace trigger chk_DateL
for insert or update on lending
COMPOUND TRIGGER
--declare
L_Date int;
avail varchar2(10);
subtype copy_booksRec is lending%ROWTYPE;
type copied_bks is table of copy_booksRec;
cbks copied_bks := copied_bks();

before each row is 
begin
  cbks.extend;
  cbks(cbks.last).cb_num := :new.cb_num;
  cbks(cbks.last).sb_num := :new.sb_num;
end before each row;

before statement is
begin
  for i in cbks.first .. cbks.last loop
    select loancode into avail from copy_books where num = cbks(i).cb_num;
    select count(date_L) into L_Date from lending where sb_num = cbks(i).sb_num and date_L = cbks(i).date_L;
      if (L_Date = 0 and avail = 'Loan') then
        update copy_books set loancode = 'Not' where num = cbks(i).cb_num;
        cbks.delete;
--        cbks(i).date_L := cbks(i).date_L;
    else
      dbms_output.put_line('You can only make ONE LOAN at a time! You have already loaned a book on ' || L_Date);
      cbks.delete;
    end if;
  end loop;
--  FORALL i IN cbks.first .. cbks.last
--      insert into lending values cbks(i);
    cbks.delete;
  end before statement;
end chk_DateL;
/
show errors

这一切都成功编译,但当我尝试插入样本记录时:

insert into lending values (2, 700, '10-MAR-14');

它引发了一个来自触发线18的数字错误。尽管我付出了努力,但我不知道需要修复什么。

3 个答案:

答案 0 :(得分:5)

您不应指望Oracle的默认日期格式将字符串文字转换为date值,您应该明确定义您使用的格式:

insert into lending values (2, 700, to_date('10-MAR-14', 'DD-MON-YY'));

答案 1 :(得分:3)

虽然日期格式问题是有效点,但这不会导致您的错误。它来自第18行,即for ... loop行:

before statement is
begin
  for i in cbks.first .. cbks.last loop

您已从触发器的cbks部分扩展并填充before row。当before statement部分触发时,cbks为空,因为行级触发器尚未触发。这是导致first错误的lastORA-06502: PL/SQL: numeric or value error引用。

您可以使用简单的匿名块来演示相同的内容:

declare
  type my_type is table of dual%rowtype;
  my_tab my_type := my_type();
begin
  for i in my_tab.first .. my_tab.last loop
    null;
  end loop;
end;
/

ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 5

SQL Fiddle;您可以看到adding an extend可以避免它,但这对您的版本没有任何帮助,因为您似乎想要行值。 (您可以使用extend消除代码中的错误,但不太可能执行您想要的操作。

我真的不确定你在这里想要达到的目标,所以我对你需要做的事情没有任何建议。

答案 2 :(得分:2)

正如Mureinik已经说过的,Oracle不知道如何将varchar2转换为date数据类型,你应该明确地使用date。但是在我看来,使用日期文字而不是使用to_date比使用to_date函数更明确

insert into lending values (2,700,date '2014-03-10');

顺便说一句,您只需通过更改当前会话并安装所需的日期格式来更改NLS设置