检查外表oracle中不存在的值的过程

时间:2015-12-01 04:07:53

标签: oracle stored-procedures foreign-keys

我的要求是编写一个在COUNTRIES表中添加值的过程。但是,首先应检查另一个表中是否存在相应的值,REGIONS是否为外键。仅当值存在时才允许插入到COUNTRIES表中。否则,没有。

我写了一段代码,但是却抛出了一堆错误:

  

ORA-00950缺少关键字PLS-00103当遇到符号THEN时   期待以下之一:(开始案例声明和例外   exit)(一个绑定变量)(继续关闭当前删除提取锁)

我写了这段代码:

var WKT = new ol.format.WKT();
WKT.writeFeatures(drawsource.getFeatures(), { rightHanded: true, dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' })

有人可以指导我做错了什么以及如何修改查询?

2 个答案:

答案 0 :(得分:1)

这不是强制执行外键的正确方法。它在多用户环境中不起作用,因为我们无法看到其他用户在未提交的会话中正在做什么。因此,当其他用户即将提交删除时,您的代码可能会找到REGION,或者相反,当其他人即将提交插入时,您的代码可能无法找到REGION。

将其留给Oracle的内置功能会好得多。

  1. 定义(并启用!)REGION和COUNTRIES之间的实际外键约束。
  2. 只需插入COUNTRIES表。
  3. 处理异常阻止中的外键冲突。
  4. 此解决方案使用PRAGMA EXCEPTION_INIT为此目的定义特定异常。 Find out more

    create or replace procedure addi1 (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
        region_not_found exception;
        pragma exception_init(region_not_found, -2291);
    begin
        insert into countries(country_id, country_name,region_id)
        values (c_cntry_id, c_cntr_name,c_rgn_id);
    exception
        when region_not_found then
            dbms_output.put_line(c_rgn_id||' is not a valid REGION id'); 
            raise;
    end addi1;
    /
    

    请注意,它会引发异常;这意味着调用程序知道插入失败,因此可以对下一步做出明智的选择。

    为了完整起见,这里是检查记录是否存在的语法。

    create or replace procedure addi1 (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
        region_exists pls_integer;
    begin
        begin
            select 1 into region_exists
            from regions r 
            where r.region_id = c_rgn_id;
        exception
            when no_data_found then
                region_exists := 0;
        end;
        if region_exists = 1 then
             ...
    

    但正如我所说,不要这样做。

      

    "它给了我ORA-00001"

    很明显,您已经定义了ID为'Ff'的COUNTRIES记录。如果要干净地处理异常,可以使用预定义的DUP_VAL_ON_INDEX异常:

         when DUP_VAL_ON_INDEX then
             dbms_output.put_line('There is an existing COUNTRIES record with an ID of' || c_cntry_id); 
    

    在现实生活中,我们应该总是提出一个例外:它是调用程序判断错误严重程度的特权。但如果你愿意,可以随意压制错误。

答案 1 :(得分:0)

只是回答你的语法问题:

你总是选择FROM某事。您的查询中缺少from并且有一个;在它的中间。

select case
             when exists (select r.region_id
                     from regions r
                    where r.region_id in (select region_id
                                            from regions)

                   ) then
              1
             else
              0
          end
     into l_exst
     from dual;

这部分查询有些奇怪:

select r.region_id
from regions r
where r.region_id in (select region_id
                      from regions)

你认为部分是必要的吗?