按顺序更新oracle数据库中的列值

x4shl7ld  于 2023-01-01  发布在  Oracle
关注(0)|答案(2)|浏览(288)

我需要在oracle数据库的sql查询帮助。
我在这里用一个假想的表格来解释这个问题。
假设我们有顾客桌

因此,此内部计数器基于customer_type(即,对于每个客户类型,它从1开始,直到最大行数)。在进行测试时,我已将internal_counter更新为null

现在我想重新分配序号给他们(例如企业客户),我不确定下面的查询。

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;

您认为这是正确的查询吗?
我在这里问,因为我不是数据库Maven,不想把事情搞得更糟。

iswrvxsc

iswrvxsc1#

不要使用PL/SQL和循环;只需在单个SQL查询中执行此操作,因为与为每一行运行单独更新相比,这样会更快,并且生成的日志文件条目也少得多:

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;

但是,如果您已经将值更新为NULL,那么首先要做的事情是尝试ROLLBACK并撤消您所做的任何未提交的更改,因为这可能会(如果您没有使用COMMIT语句或任何DDL语句)恢复以前的值。

t5fffqht

t5fffqht2#

使用像ROW_NUMBER这样的窗口函数来生成internal_counter,因为它不是一个简单的顺序计数器,然后使用MERGE语句将其提供给表的更新:

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;

相关问题