微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PL / SQL:如何从多个表中删除行

如何解决PL / SQL:如何从多个表中删除行

您好,我是PL / sql的新手,我想编写一个从多个表中删除国家/地区的过程 它不会编译,我也不会怎么做

由于有多个表,我应该输入什么参数? 如果某个国家/地区的名称是某些表中的主键,该如何删除其国家/地区名称

表是

交叉

NRiver   |   NameC
-------------------
Nile     |  Egypt

边界

NameC    |    NameB            |  Lenght
------------------------------------------
Canada   |    United States     |  76483

定位

NMountain  | NameC
------------------
1          | Canada

这是代码

Create or replace procedure DELETECOUNTRY (
        pname country.name%type) as

begin

delete from country where name=pname;
commit;
             dbms_output.put_line('Country deleted:' || ' '|| pnom );

delete from border where name=pname;
commit;
             dbms_output.put_line('Country deleted:' || ' '|| pnom );

delete from cross where name=pname;
commit;
             dbms_output.put_line('Country deleted:' || ' '|| pnom );

delete from locate where name=pname;
commit;
             dbms_output.put_line('Country deleted:' || ' '|| pnom );

EXCEPTION 
 
        when NO_DATA_FOUND then
            dbms_output.put_line('this country doesnt exist');

END;
/

谢谢

解决方法

您的问题有很多未知的东西:

  • 我已经问过要添加Oracle标记。

  • 还添加一些样本数据和扩展结果。

  • 此外,您具有与parametar中相同的pname,但打印出pnom:

    dbms_output.put_line('Country deleted:' || ' '|| pnom );
    

这里是一个演示,显示在更正pnom时代码正常。如果问题出在其他地方,请检查前两个请求:

DEMO

这里是您可以尝试欺骗主键值的一种选择:

create procedure DELETE_COUN (pname varchar) 
AS

  pnum1 int;
  pnum2 int;
  err_num NUMBER;
  err_msg VARCHAR2(100);
  
begin

pnum1 := 0;
pnum2 := 0;

LOOP

  begin
    delete from country 
    where name = pname;

    commit;
    
    pnum1 := 0;
    
  EXCEPTION 
    when others then
      err_num := SQLCODE;
      DBMS_OUTPUT.PUT_LINE(err_num);
      if err_num = '-2292' then
        pnum1 := pnum1 - 1;
      else
        raise_application_error(-20001,'Deleting data from table country was not succesful!');
      end if;
  end;
  
  begin
    delete from border 
    where name = pname;

    commit;

    pnum2 := 0;
    
  EXCEPTION 
    when others then
      err_num := SQLCODE;
      if err_num = '-2292' then
        pnum2 := pnum2 -1;
      else
        raise_application_error(-20001,'Deleting data from table border was not succesful!');
      end if;  
  end;
    
  EXIT WHEN pnum1 = 0 and pnum2 = 0;

END LOOP;

            
END;
/

这是一个演示:

DEMO

,

无需重复删除语句,只需使用动态SQL,并考虑公共列名NameC,该列名应作为每个where子句中的过滤条件而存在,例如

SET SERVEROUTPUT ON
CREATE OR REPLACE PROCEDURE Delete_Country(pname country.NameC%type) AS
  v_tab OWA.vc_arr;
  j     INT := 0;
BEGIN
  v_tab(1):= 'country';
  v_tab(2):= 'border';
  v_tab(3):= 'cross';
  v_tab(4):= 'locate';
  FOR i IN 1..v_tab.count
  LOOP
      EXECUTE IMMEDIATE 'DELETE '||v_tab(i)||' WHERE NameC=:cname' USING pname;
      IF SQL%ROWCOUNT > 0 THEN
         DBMS_OUTPUT.PUT_LINE('Country '||pname||' is deleted from the table '||v_tab(i));
         j :=+ SQL%ROWCOUNT;
      END IF;
      COMMIT;
  END LOOP;
  IF j = 0 THEN
     DBMS_OUTPUT.PUT_LINE('Country '||pname||' doesn''t exists within any of the tables ');
  END IF;
END;
/

其中v_tab是一个字符串类型的数组,代表每个表名。 j代表控制任何一个表中国家/地区名称的值的存在,这意味着如果未在循环内更新该国家/地区名称,则没有此类数据。对于每个单独的表,通过DML(SQL%ROWCOUNT)为每个成功处理的行,对j的更新程序值(DELETE)进行递增,并由每个COMMIT进行重置。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。