更新不同数据类型的单列

Update single column of different data types

我在 Oracle 数据库中有三个 table: 内容,CONTENT_DATA,DATA_TYPE

CONTENT_DATA中的数据记录如下:

PK_ID  DATA_TYPE_ID  CONTENT_ID   VALUE
1         1             1           0
2         2             1          100
3         3             1          200

我需要根据 CONTENT_DATA table 中的 DATA_TYPE_ID 将 'value' 列更新为其他 'value' 列的总和,这个过程应该是为每个 CONTENT_ID 完成。 例如:VALUE(DATA_TYPE(3)) = SUM(VALUE(DATA_TYPE(1)), VALUE(DATA_TYPE(2)))

我创建了如下所示的程序。但是它运行得很慢。有没有更好的选择来处理这样的问题?

CREATE OR REPLACE PROCEDURE UPDATE_DATA
AS
    CURSOR your_cursor is
        SELECT DISTINCT CONTENT_ID FROM CONTENT_DATA;
    item your_cursor%rowtype;
BEGIN
    OPEN your_cursor;
    loop
        FETCH your_cursor INTO item;
        UPDATE CONTENT_DATA SET VALUE = 
             (SELECT  SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN(1,2)
                                        AND CONTENT_ID = item.CONTENT_ID) 
        WHERE CONTENT_ID = item.CONTENT_ID AND DATA_TYPE_ID = 3;  
    
        UPDATE CONTENT_DATA SET VALUE = (SELECT  SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID  IN(3,4,5,6,7,8,9)
                                        AND CONTENT_ID = item.CONTENT_ID)
        WHERE CONTENT_ID = item.CONTENT_ID
        AND DATA_TYPE_ID = 10;           
        
        
        UPDATE CONTENT_DATA SET VALUE = (SELECT  SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN( 10,11,12,13,14)
                                            AND CONTENT_ID = item.CONTENT_ID)
        WHERE CONTENT_ID = item.CONTENT_ID
        AND DATA_TYPE_ID = 15;
    
    end loop;
    close your_cursor;
END;

我认为您不需要为此使用游标。我为您构建了一个测试用例以查看它的行为方式,然后您只需更改三个游标中的三个更新语句即可,而无需使用游标

测试用例

SQL> create table my_merge_test ( pk_id number, data_type_id number, content_id number, value number );

SQL> select * from my_merge_test ;

     PK_ID DATA_TYPE_ID CONTENT_ID      VALUE
---------- ------------ ---------- ----------
         1            1          1          0
         2            2          1        100
         3            3          1        200
         4            3          1        120
         5            3          1        120

现在,让我们看看你想在第一次更新时做什么:

UPDATE CONTENT_DATA SET VALUE = 
             (SELECT  SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN(1,2)
                                        AND CONTENT_ID = item.CONTENT_ID) 
        WHERE CONTENT_ID = item.CONTENT_ID AND DATA_TYPE_ID = 3;  

对于数据类型为 1 或 2 的每个 content_id,当项目相同且数据类型为3.其他的更新逻辑是一样的,只是值不同

不使用游标,您可以使用 with 子句在一个语句中执行操作

SQL> update my_merge_test t
  2  set t.value = (
  3    with source as ( select  content_id, SUM(NVL(value,0)) as sum_value from my_merge_test where DATA_TYPE_ID IN(1,2)
                   group by  content_id
        )
  select h.sum_value
  from  source h
  where h.content_id = t.content_id and t.data_type_id = 3
) where t.data_type_id = 3
;  4    5    6    7    8    9   10

3 rows updated.

SQL> select * from my_merge_test ;

     PK_ID DATA_TYPE_ID CONTENT_ID      VALUE
---------- ------------ ---------- ----------
         1            1          1          0
         2            2          1        100
         3            3          1        100
         4            3          1        100
         5            3          1        100

SQL>

那么第二次更新就是

update my_merge_test t
set t.value = (
  with source as ( select  content_id, SUM(NVL(value,0)) as sum_value from my_merge_test where DATA_TYPE_ID IN (3,4,5,6,7,8,9)
               group by  content_id 
    )
  select h.sum_value 
  from  source h
  where h.content_id = t.content_id and t.data_type_id = 10
) where t.data_type_id = 10 
;

第三个是

update my_merge_test t
set t.value = (
  with source as ( select  content_id, SUM(NVL(value,0)) as sum_value from my_merge_test where DATA_TYPE_ID IN ( 10,11,12,13,14)
               group by  content_id 
    )
  select h.sum_value 
  from  source h
  where h.content_id = t.content_id and t.data_type_id = 15
) where t.data_type_id = 15 
;

用您的表格替换名称,让我知道它是否满足您的需要。