在不合并的情况下重写 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
我需要在不合并的情况下重写以下过程。 所以基本上 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