【问题标题】:Oracle Pl/SQL procedure to update values of one table to anotherOracle Pl/SQL 过程将一个表的值更新到另一个表
【发布时间】:2013-10-17 09:53:30
【问题描述】:

我的要求是我有两个具有两个属性的表。我编写了一个程序,它应该从 table1 获取值(sor_ID)并根据主键在表 2 中更新它。

Table 1 
-------
Primary Key | Sor_ID

AAA         | 100

BBB         | 200

Table 2
-----
Foreign Key | Sor_ID

AAA         | NULL

BBB         | NULL

create or replace
    Procedure UPDDATE_SORID_2 
IS
    s_id VARCHAR2(256 byte);

    CURSOR C1 IS
    SELECT A.SOR_INSTRMNT_ID
    FROM TEST_TABLE B,TEMP_SOR_ID A
    where A.INSTRMNT_KEY=B.INSTRMNT_KEY;
BEGIN

    open c1;
    loop
    fetch c1 into s_id;

    update TEST_TABLE set SOR_INSTRMNT_ID=S_ID; 

    commit;
    end LOOP;
    close c1;

EXCEPTION
    WHEN OTHERS THEN
    RAISE_APPLICATION_ERROR(-20001,'An error was encountered - '
                                    ||SQLCODE||' -ERROR'||SQLERRM);
end;

此过程即使在运行数小时后也不会返回任何更新。请推荐

【问题讨论】:

  • 您的 WHEN OTHERS 异常处理似乎是多余的。只需引发异常即可。

标签: sql debugging stored-procedures plsql oracle11g


【解决方案1】:

您不需要光标来执行此操作。

如果表之间存在外键关系,则可以在两个连接表的保留键视图上进行更新。

一般模式是:

Update (
  select parent_table.key   parent_key,
         child_table.key    child_key,
         parent_table.value parent_value,
         child_table.value  child_value
  from   parent_table
  join   child_table  on child_table.key = parent_table.key)
set
  child_value = parent_value;

这将比基于 PL/SQL 游标的方法更快、更健壮。

顺便说一句,您还可以使用类似的删除键保留视图的技术来删除子记录。

当然,这并不能回答为什么要将父属性放在子表中的问题。

【讨论】:

  • 谢谢....我已经尝试过加入,但有目的需要它作为存储过程..请建议
  • 请建议是否可以在程序的执行阶段给出更新查询...begin 之后......还建议使用游标处理它的方法(老式方式)
  • 不知道你在问什么
  • 不。您不应该为此使用光标。为什么你认为你需要一个光标?
【解决方案2】:

我注意到您的程序存在一些问题。

1) 它永远运行,因为您的循环中没有 EXIT。
2)您的更新语句每次都会更新整个表,因为您没有使用 WHERE 子句。

我建议你改变如下:

CREATE OR REPLACE PROCEDURE upddate_sorid_2
IS
    s_id VARCHAR2(256 byte);
    s_instrmnt_key VARCHAR2(256 byte);

    CURSOR c1 IS
    SELECT a.sor_instrmnt_id, a.instrmnt_key
    FROM test_table b,temp_sor_id a
    WHERE a.instrmnt_key = b.instrmnt_key;
BEGIN

    OPEN c1;
    LOOP
    FETCH c1 INTO s_id, s_instrmnt_key;

    EXIT WHEN c1%NOTFOUND;

    UPDATE test_table
    SET sor_instrmnt_id = s_id
    WHERE INSTRMNT_KEY = s_instrmnt_key; 

    END LOOP;

    CLOSE c1;

    COMMIT;

EXCEPTION
    WHEN OTHERS THEN
    RAISE_APPLICATION_ERROR(-20001,'An error was encountered - '
                                    ||SQLCODE||' -ERROR'||SQLERRM);
end;

【讨论】:

  • 谢谢..但是发生的情况是所有记录都更新了相同的 sor_id
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-25
相关资源
最近更新 更多