更新时间:2023-01-22 16:32:04
您在参数列表后加了分号,而不是as.试试:
You've got a semi-colon after the list of parameters instead of as. Try:
CREATE OR REPLACE PROCEDURE add_vals (c_cntry_id OUT COUNTRIES.COUNTRY_ID%TYPE,
c_cntr_name IN COUNTRIES.COUNTRY_NAME%TYPE,
c_rgn_id IN COUNTRIES.REGION_ID%TYPE)
AS
BEGIN
INSERT INTO countries(COUNTRY_ID, COUNTRY_NAME,REGION_ID)
values (user_seq.nextval, c_cntr_name,c_rgn_id)
Returning country_id into c_cntry_id;
EXCEPTION
WHEN dup_val_on_index
THEN
c_cntry_id := null;
END;
/
还要注意,我已经使用returning子句来设置c_cntry_id的值.
Note also that I have used the returning clause to set the value of c_cntry_id.
查看已编辑的代码,现在的问题是,您的过程中在IS
和BEGIN
Looking at your edited code, the issue now is that you have got DECLARE
in your procedure between the IS
and the BEGIN
此外,由于您正在使用序列值将行插入表中-希望这是唯一可以插入行的点-永远不会导致dup_val_on_index异常.
Also, since you're using a sequence value to insert rows into the table - and, hopefully, this is the only point at which rows could be inserted - that shouldn't ever result in a dup_val_on_index exception.
由于在country_name列上有一个附加的唯一约束,我已经敲出了一个将创建dup_val_on_index的测试用例,并且还向您展示了两种创建代码的方法-作为过程和函数,以及演示怎么称呼他们:
I've knocked up a test case that will create the dup_val_on_index due to an additional unique constraint on the country_name column, and also shown you two ways of creating the code - as a procedure and as a function, as well as demonstrating how to call them:
drop table countries;
drop sequence user_seq;
drop procedure add_country_pr;
drop function add_country_fn;
create table countries (country_id integer primary key,
country_name varchar2(50) unique not null,
region_id integer);
create sequence user_seq
start with 1
maxvalue 99999
minvalue 1
nocycle
cache 20
noorder;
create or replace procedure add_country_pr (c_cntry_id out countries.country_id%type,
c_cntr_name in countries.country_name%type,
c_rgn_id in countries.region_id%type)
is
begin
insert into countries (country_id, country_name,region_id)
values (user_seq.nextval, c_cntr_name,c_rgn_id)
returning country_id into c_cntry_id;
exception
when dup_val_on_index
then
c_cntry_id := null;
end add_country_pr;
/
create or replace function add_country_fn (c_cntr_name in countries.country_name%type,
c_rgn_id in countries.region_id%type)
return integer
is
v_cntry_id integer;
begin
insert into countries (country_id, country_name,region_id)
values (user_seq.nextval, c_cntr_name,c_rgn_id)
returning country_id into v_cntry_id;
return v_cntry_id;
exception
when dup_val_on_index
then
return null;
end add_country_fn;
/
set serveroutput on;
-- anonymous block used to call the above procedure/function
declare
v_cntry_id integer;
begin
add_country_pr (c_cntry_id => v_cntry_id, -- variable to hold the value of the out parameter
c_cntr_name => 'GBR',
c_rgn_id => 1);
commit;
dbms_output.put_line('add_country_pr 1st call, country_id = "'||v_cntry_id||'"');
add_country_pr (c_cntry_id => v_cntry_id, -- variable to hold the value of the out parameter
c_cntr_name => 'GBR',
c_rgn_id => 1);
commit;
dbms_output.put_line('add_country_pr 2nd call, country_id = "'||v_cntry_id||'"');
v_cntry_id := add_country_fn (c_cntr_name => 'USA',
c_rgn_id => 2);
commit;
dbms_output.put_line('add_country_fn 1st call, country_id = "'||v_cntry_id||'"');
v_cntry_id := add_country_fn (c_cntr_name => 'USA',
c_rgn_id => 2);
commit;
dbms_output.put_line('add_country_fn 2nd call, country_id = "'||v_cntry_id||'"');
end;
/
add_country_pr 1st call, country_id = "1"
add_country_pr 2nd call, country_id = ""
add_country_fn 1st call, country_id = "3"
add_country_fn 2nd call, country_id = ""