Home > OS >  Update the column value sequentially in oracle db
Update the column value sequentially in oracle db

Time:12-30

I need a help in sql query for oracle database .

I am using a imaginary table here to explain the problem.

suppose we have customers table

internal_counter, customer_name, customer_type
1                     X               Business
1                     Y               Retail
2                     z               Business

so this internal counter is based on customer_type (i.e. for each customer type it begins from 1 till the max rows) . while doing testing I have updated the internal_counter to null .

enter image description here

now I want reassign the sequential number to them (for example Business customers) and I am not sure about below query .

    DECLARE
    VAL NUMBER := 1;
BEGIN
    FOR REC IN ( select * from customers where customer_type = 'Business' )
    LOOP
        UPDATE customers SET internal_counter = VAL ;       
        VAL := VAL  1;
    END LOOP;
END;

do you think its the right query ?

I am asking here because I am not db expert and don't want to mess things further .

CodePudding user response:

Don't use PL/SQL and loops; just do it in a single SQL query as it will be quicker and generate far fewer entries into the log files compared to running individual updates for each row:

MERGE INTO customers dst
USING (
  SELECT ROWID AS rid,
         ROWNUM AS rn
  FROM   customers
  WHERE  customer_type = 'Business'
) src
ON (src.rid = dst.ROWID)
WHEN MATCHED THEN
  UPDATE
  SET internal_counter = src.rn;

However, if you have updated the values to NULL then the first thing to do is to try ROLLBACK and undo any changes you have made that are uncommitted as that may (if you have not used a COMMIT statement or any DDL statements) restore the pervious values.

CodePudding user response:

Use a windowing function like ROW_NUMBER to generate your internal_counter, since it's not a simple sequential counter. Then feed that into an update of the table using the MERGE statement:

merge into customers
using (select rowid as rid,
              ROW_NUMBER() OVER (PARTITION BY customer_type ORDER BY customer_name) internal_counter
         from customers) src
on (customers.rowid = src.rid)
when matched then update set customers.internal_counter = src.internal_counter;
  • Related