插入前检查表中非重复行的过程(Oracle)

时间:2015-11-30 19:32:16

标签: oracle

我在oracle中编写了一个过程(使用此处的指导)来检查表中的任何重复值,以便具有相同countryId的国家/地区应该返回一些错误消息,因为countryId是国家/地区表中的PK.Here it:

   CREATE OR REPLACE PROCEDURE add_values4 (c_cntry_id IN OUT COUNTRIES.COUNTRY_ID%TYPE,
                                       c_cntr_name IN COUNTRIES.COUNTRY_NAME%TYPE, 
                                       c_rgn_id IN COUNTRIES.REGION_ID%TYPE)
IS
DECLARE
   outputValue CHAR  := 'JJ';
BEGIN
  INSERT INTO countries(COUNTRY_ID, COUNTRY_NAME,REGION_ID)
    values (user_seq.nextval, c_cntr_name,c_rgn_id);
  c_cntry_id := user_seq.currval;
EXCEPTION
  WHEN dup_val_on_index
  THEN 
    c_cntry_id := null;
END;
/

然而,当我尝试创建这个程序时,它给了我错误PLS-00103。任何想法可能有什么问题? (语法有什么用吗?)。自48小时以来我一直在尝试,但没有太大的成功。在这里感谢一些帮助。

提前Tx

2 个答案:

答案 0 :(得分:0)

你在参数列表后面有一个分号而不是。尝试:

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;
/

另请注意,我已使用returns子句设置c_cntry_id的值。

查看已修改的代码,现在的问题是您的DECLAREIS

之间的程序已BEGIN

此外,由于您正在使用序列值将行插入表中 - 并且希望这是唯一可以插入行的点 - 这不应该导致dup_val_on_index异常。

我已经敲了一个测试用例,由于country_name列上有一个额外的唯一约束,它将创建dup_val_on_index,并且还向您展示了两种创建代码的方法 - 作为过程和函数,以及演示如何称呼它们:

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 = ""

答案 1 :(得分:0)

参数阻止后你有一个分号,而你错过了ISAS条款:

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)
IS
BEGIN
  INSERT INTO countries(COUNTRY_ID, COUNTRY_NAME,REGION_ID)
    values (user_seq.nextval, c_cntr_name,c_rgn_id);
  c_cntry_id := user_seq.currval;
EXCEPTION
  WHEN dup_val_on_index
  THEN 
    c_cntry_id := null;
END;
/