foreach我的表行并更新我的ROW_NUMBER列

时间:2015-10-21 10:19:44

标签: sql oracle plsql sql-update

我想创建一个脚本pl / sql,我可以修改我的列ROW_NUMBER的值(第一次ROW_NUMBER的值等于NULL)。

这是我的表'A'的结构:

CREATE TABLE A
   (
    "NAME" VARCHAR2(25 BYTE), 
    "NUM" NUMBER(10,0)
   )

如果列'NAME'等于'DEB',我想预先处理表A的所有行并将我的列'NUM'递增1。

我想得到如下结果:

enter image description here

我创建了一个pl / sql脚本:

DECLARE
 INcrmt NUMBER(4):=1;
 line WORK_ODI.TEST_SEQ%ROWTYPE;--before fetch it returns 0
 CURSOR c_select IS
 SELECT ROW_NUMBER,VALUE FROM WORK_ODI.TEST_SEQ;
BEGIN
 OPEN c_select;
  LOOP
   FETCH c_select INTO line;
   DBMS_OUTPUT.PUT_LINE(line.VALUE);
   if line.VALUE like '%DEB%'
   then
    UPDATE WORK_ODI.TEST_SEQ SET ROW_NUMBER = INcrmt WHERE VALUE=line.VALUE;
    INcrmt := INcrmt + 1;
   end if;
   if line.VALUE not like '%DEB%'
    then
    UPDATE WORK_ODI.TEST_SEQ SET ROW_NUMBER = INcrmt WHERE VALUE=line.VALUE;
   end if;
   EXIT WHEN c_select%NOTFOUND;
  END LOOP;
 CLOSE c_select;
 COMMIT;
END;

DECLARE
 INcrmt NUMBER(4):=1;
 line WORK_ODI.TEST_SEQ%ROWTYPE;--before fetch it returns 0
 CURSOR c_select IS
 SELECT ROW_NUMBER,VALUE FROM WORK_ODI.TEST_SEQ;
BEGIN
 OPEN c_select;
  LOOP
   FETCH c_select INTO line;
   DBMS_OUTPUT.PUT_LINE(line.VALUE);
   if line.VALUE like '%DEB%'
   then
    UPDATE WORK_ODI.TEST_SEQ SET ROW_NUMBER = INcrmt WHERE VALUE=line.VALUE;
    INcrmt := INcrmt + 1;
   end if;
   if line.VALUE not like '%DEB%'
    then
    UPDATE WORK_ODI.TEST_SEQ SET ROW_NUMBER = INcrmt WHERE VALUE=line.VALUE;
   end if;
   EXIT WHEN c_select%NOTFOUND;
  END LOOP;
 CLOSE c_select;
 COMMIT;
END;

但是效果不好,请看一下它给我的结果:

enter image description here

请任何人都可以帮助我

1 个答案:

答案 0 :(得分:6)

首先,您应该拥有某种Aid列。在Oracle 12+中,您可以使用标识。在早期版本中,您可以使用序列。这提供了基于插入顺序的表中行的排序。

其次,你可以在输出上做你想做的事情:

select a.*,
       sum(case when a.name like 'DEB%' then 1 else 0 end) over (order by aid) as row_number
from a;

如果确实需要保留表中的值,则可以使用merge语句为现有行分配值(aid列非常方便)。之后你需要一个触发器来维护它。

我的建议是对数据进行计算,而不是将值存储在数据中。使用updatedelete来维护这些值似乎是一种真正的痛苦。