简体   繁体   中英

foreach rows of my table and update my ROW_NUMBER column

I would like to create a script pl/sql where I can modify the value of my column ROW_NUMBER (the first time the value of ROW_NUMBER equal NULL).

This is the structure of my table 'A' :

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

I would like to foreach all rows of table A and increment my Column 'NUM' by 1 if Column 'NAME' equal 'DEB'.

I would like to get the result like :

在此处输入图片说明

I created one pl/sql script :

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;

but this is not work well , please take a look at what it gives me as result :

在此处输入图片说明

please anybody can help me

First, you should have an Aid column of some sort. In Oracle 12+, you can use an identity. In earlier versions, you can use a sequence. This provides an ordering for the rows in the table, based on insert order.

Second, you can do what you want on output:

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

If you really need to keep the values in the table, then you can use a merge statement to assign values to existing rows (the aid column is very handy for this). You will need a trigger afterwards to maintain it.

My suggestion is to do the calculation on the data, rather than storing the value in the data. Maintaining the values with update s and delete s seems like a real pain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM