PL/SQL 中的 ORA-10400 错误,无法使用过程在 table 中自动生成 tran_no 字段
ORA-10400 error in PL/SQL, cannot auto generate tran_no field in table using procedure
T_Acc_Details 是一个 table 用于存储具有给定字段的人的帐号详细信息。
create table T_Acc_Details(
acc_no number(5) primary key,
acc_holder_name varchar2(50),
acc_type varchar2(5) check (acc_type in ('SB', 'CA', 'FD')),
opening_date date,
balance_amt number(10,2)
)
我还在字段中输入了如下值:
insert into T_Acc_Details values(10000, 'A', 'SB', to_date('23/11/2019', 'DD/MM/YYYY'), 1000.2);
其次,我创建了交易详情 table,其中要根据存款或取款插入值。 table查询如下:
create table T_Tran_Details(
tran_no number(5) primary key not null,
acc_no number(5),
tran_type varchar2(5) check (tran_type in ('w', 'd')),
transaction_date date,
amount number(10,2),
foreign key(acc_no) references T_Acc_Details(acc_no)
)
此外,这是我的程序。在这里,我将 acc_no、金额、tran_type 作为参数,并从余额金额和 tran_no 中获取当前余额作为变量。我正在尝试编写存款部分的逻辑。此外,tran_no.
的自动生成值
create or replace procedure pr_updateBal(
p_acc_no T_Acc_Details.Acc_No%type,
p_amount T_Tran_Details.Amount%type,
p_tran_type T_Tran_Details.Tran_Type%type
) is
p_curr_bal T_Acc_Details.Balance_Amt%type;
p_tran_no T_Tran_Details.Tran_No%type;
begin
select max(nvl(tran_no,0)+1) into p_tran_no from T_Tran_Details;
select T_Acc_Details.Balance_Amt into p_curr_bal from T_Acc_Details where T_Acc_Details.Acc_No = p_acc_no;
if(p_tran_type = 'd') then
p_curr_bal := p_curr_bal + p_amount;
insert into T_Tran_Details(tran_no, acc_no, tran_type, transaction_date, amount)
values (p_tran_no, p_acc_no, p_tran_type, to_date(sysdate,'DD/MM/YY'), p_amount);
update T_Acc_Details
set T_Acc_Details.Balance_Amt = p_curr_bal;
dbms_output.put_line('Amount deposited!');
end if;
end pr_updateBal;
当我尝试测试代码和 运行 时,插入 T_Tran_Details(.. 会导致此错误。这些值怎么会为空?我已经采用 tran_no 作为主键。
error
我发现了你的问题,所以这一行:
select max(nvl(tran_no,0)+1) into p_tran_no from T_Tran_Details;
生成一个空值 bcs 你的 table 是空的,当你简单地写:
Select max(nvl(tran_no,0)+1) max from T_Tran_Details;
你在最大列中得到一个空值。
要生成新的 tran_no 尝试使用一个序列或像这样:
for i in (select max(tran_no) max from T_Tran_Details) loop
if i.max is null then p_tran_no:=0;
else p_tran_no:=i.max +1;
end if;
end loop;
所以你的整个代码看起来像这样:
create or replace procedure pr_updateBal(
p_acc_no T_Acc_Details.Acc_No%type,
p_amount T_Tran_Details.Amount%type,
p_tran_type T_Tran_Details.Tran_Type%type
)
is
p_curr_bal T_Acc_Details.Balance_Amt%type;
p_tran_no T_Tran_Details.Tran_No%type;
begin
for i in (select max(tran_no) max from T_Tran_Details) loop
if i.max is null then p_tran_no:=0;
else p_tran_no:=i.max+1;
end if;
end loop;
select T_Acc_Details.Balance_Amt into p_curr_bal from T_Acc_Details
where T_Acc_Details.Acc_No = p_acc_no;
if(p_tran_type = 'd') then
p_curr_bal := p_curr_bal + p_amount;
insert into T_Tran_Details(tran_no, acc_no, tran_type, transaction_date, amount)
values (p_tran_no, p_acc_no, p_tran_type, to_date(sysdate,'DD/MM/YY'), p_amount);
update T_Acc_Details
set T_Acc_Details.Balance_Amt = p_curr_bal;
dbms_output.put_line('Amount deposited!');
end if;
end pr_updateBal;
T_Acc_Details 是一个 table 用于存储具有给定字段的人的帐号详细信息。
create table T_Acc_Details(
acc_no number(5) primary key,
acc_holder_name varchar2(50),
acc_type varchar2(5) check (acc_type in ('SB', 'CA', 'FD')),
opening_date date,
balance_amt number(10,2)
)
我还在字段中输入了如下值:
insert into T_Acc_Details values(10000, 'A', 'SB', to_date('23/11/2019', 'DD/MM/YYYY'), 1000.2);
其次,我创建了交易详情 table,其中要根据存款或取款插入值。 table查询如下:
create table T_Tran_Details(
tran_no number(5) primary key not null,
acc_no number(5),
tran_type varchar2(5) check (tran_type in ('w', 'd')),
transaction_date date,
amount number(10,2),
foreign key(acc_no) references T_Acc_Details(acc_no)
)
此外,这是我的程序。在这里,我将 acc_no、金额、tran_type 作为参数,并从余额金额和 tran_no 中获取当前余额作为变量。我正在尝试编写存款部分的逻辑。此外,tran_no.
的自动生成值create or replace procedure pr_updateBal(
p_acc_no T_Acc_Details.Acc_No%type,
p_amount T_Tran_Details.Amount%type,
p_tran_type T_Tran_Details.Tran_Type%type
) is
p_curr_bal T_Acc_Details.Balance_Amt%type;
p_tran_no T_Tran_Details.Tran_No%type;
begin
select max(nvl(tran_no,0)+1) into p_tran_no from T_Tran_Details;
select T_Acc_Details.Balance_Amt into p_curr_bal from T_Acc_Details where T_Acc_Details.Acc_No = p_acc_no;
if(p_tran_type = 'd') then
p_curr_bal := p_curr_bal + p_amount;
insert into T_Tran_Details(tran_no, acc_no, tran_type, transaction_date, amount)
values (p_tran_no, p_acc_no, p_tran_type, to_date(sysdate,'DD/MM/YY'), p_amount);
update T_Acc_Details
set T_Acc_Details.Balance_Amt = p_curr_bal;
dbms_output.put_line('Amount deposited!');
end if;
end pr_updateBal;
当我尝试测试代码和 运行 时,插入 T_Tran_Details(.. 会导致此错误。这些值怎么会为空?我已经采用 tran_no 作为主键。
error
我发现了你的问题,所以这一行:
select max(nvl(tran_no,0)+1) into p_tran_no from T_Tran_Details;
生成一个空值 bcs 你的 table 是空的,当你简单地写:
Select max(nvl(tran_no,0)+1) max from T_Tran_Details;
你在最大列中得到一个空值。
要生成新的 tran_no 尝试使用一个序列或像这样:
for i in (select max(tran_no) max from T_Tran_Details) loop
if i.max is null then p_tran_no:=0;
else p_tran_no:=i.max +1;
end if;
end loop;
所以你的整个代码看起来像这样:
create or replace procedure pr_updateBal(
p_acc_no T_Acc_Details.Acc_No%type,
p_amount T_Tran_Details.Amount%type,
p_tran_type T_Tran_Details.Tran_Type%type
)
is
p_curr_bal T_Acc_Details.Balance_Amt%type;
p_tran_no T_Tran_Details.Tran_No%type;
begin
for i in (select max(tran_no) max from T_Tran_Details) loop
if i.max is null then p_tran_no:=0;
else p_tran_no:=i.max+1;
end if;
end loop;
select T_Acc_Details.Balance_Amt into p_curr_bal from T_Acc_Details
where T_Acc_Details.Acc_No = p_acc_no;
if(p_tran_type = 'd') then
p_curr_bal := p_curr_bal + p_amount;
insert into T_Tran_Details(tran_no, acc_no, tran_type, transaction_date, amount)
values (p_tran_no, p_acc_no, p_tran_type, to_date(sysdate,'DD/MM/YY'), p_amount);
update T_Acc_Details
set T_Acc_Details.Balance_Amt = p_curr_bal;
dbms_output.put_line('Amount deposited!');
end if;
end pr_updateBal;