我知道之前已经解决了这个错误问题,但我似乎无法找到任何相关的解决方案,所以我发布了这个问题。
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的数字错误。尽管我付出了努力,但我不知道需要修复什么。
答案 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
错误的last
和ORA-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设置