在不合并的情况下重写 Oracle PL/SQL 过程

Rewrite Oracle PL/SQL procedure without merge

我需要在不合并的情况下重写以下过程。 所以基本上 insert/update 需要在没有合并的情况下完成,如果可能的话任何其他选择。 数据库是 Oracle12c/12.1

CREATE OR REPLACE PROCEDURE PUSH_DATA(p_id NUMBER) IS
BEGIN
MERGE INTO push_data_temp tgt
USING(
with rcte (id, data, lvl, result) 
as (
 select id, data, 1,
        regexp_substr(data,
        '("[^"]*"|[^, "]+)', 1, 1, null, 1) result
   from disp_data where id=p_id
union all
 select id, data, lvl + 1,
        regexp_substr(data, '("[^"]*"|[^, "]+)', 1, lvl + 1, null, 1)
   from rcte
where lvl <= regexp_count(data, '("[^"]*"|[^, "]+)')
 )
select *
from (
select id, lvl, replace(result,'""','') as result
from rcte
)
pivot (max(result)
FOR   (lvl) IN(1 AS col1
              ,2 AS col2
              ,3 AS col3
              ,4 AS col4
              ,5 AS col5
              ,6 AS col6
              ,7 AS col7
              ,8 AS col8
              ,9 AS col9
              ,10 AS col10
              ,11 AS col11
              ,12 AS col12))
      ) src
  ON (src.id = tgt.id)
WHEN MATCHED THEN UPDATE
 SET col1 = src.col1
   , col2 = src.col2
   , col3 = src.col3
   , col4 = src.col4
   , col5 = src.col5
   , col6 = src.col6
   , col7 = src.col7
   , col8 = src.col8
   , col9 = src.col9
   , col10 = src.col10
   , col11 = src.col11
   , col12 = src.col12
WHEN NOT MATCHED THEN 
  INSERT (id, col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11, col12)
  VALUES (src.id, src.col1, src.col2,src.col3,src.col4,src.col5,
          src.col6,src.col7,src.col8,src.col9,src.col10,src.col11,src.col12);
END;
/

@sujitmohanty 帮助我完成了手术。

我修改了程序以使用正常 loop 而不是 merge。请记住稍后更改为 merge,因为它是 insert/update 操作的最佳选择,就像您的情况一样。

我将过程参数设为可选,如果您传递 pid 它将对特定的 pid 执行 insert/update 否则只需传递 null 它将对所有参数执行。

Note: For huge data you may need to rethink on using bulk collect operation to do the insert or update ( if only required)

CREATE OR REPLACE PROCEDURE PUSH_DATA(p_id NUMBER) IS
  CURSOR cur_data IS
    WITH rcte (id, data, lvl, result)
    AS (
         SELECT id, data, 1,
                regexp_substr(data,
                '("[^"]*"|[^, "]+)', 1, 1, null, 1) result
           FROM disp_data where id=coalesce(p_id,id)
        UNION ALL
         SELECT id, data, lvl + 1,
                regexp_substr(data, '("[^"]*"|[^, "]+)', 1, lvl + 1, null, 1)
           FROM rcte
        WHERE lvl <= regexp_count(data, '("[^"]*"|[^, "]+)')
       )
    SELECT *
    FROM (SELECT id, lvl, replace(result,'""','') as result
            FROM rcte)
    PIVOT (MAX(result)
     FOR (lvl) IN(1 AS col1
                  ,2 AS col2
                  ,3 AS col3
                  ,4 AS col4
                  ,5 AS col5
                  ,6 AS col6
                  ,7 AS col7
                  ,8 AS col8
                  ,9 AS col9
                  ,10 AS col10
                  ,11 AS col11
                  ,12 AS col12));
   var cur_data%ROWTYPE;
BEGIN
  OPEN cur_data;
  LOOP
    FETCH cur_data INTO var;
    EXIT WHEN cur_data%NOTFOUND;
    UPDATE push_data_temp
    SET col1 = var.col1
      , col2 = var.col2
      , col3 = var.col3
      , col4 = var.col4
      , col5 = var.col5
      , col6 = var.col6
      , col7 = var.col7
      , col8 = var.col8
      , col9 = var.col9
      , col10 = var.col10
      , col11 = var.col11
      , col12 = var.col12
    WHERE ID = var.id;
    IF SQL%ROWCOUNT = 0
    THEN
       INSERT INTO push_data_temp(id, col1, col2, col3, col4, col5,
                                  col6, col7, col8, col9, col10, col11, col12)
          VALUES (var.id, var.col1, var.col2,var.col3,var.col4,var.col5,
                  var.col6,var.col7,var.col8,var.col9,var.col10,var.col11,var.col12);
    END IF;
  END LOOP;
END;
/

测试:-

BEGIN
   push_data(p_id=>null);
END;
/

终于Dbfiddle