原創文章,轉載請注明出處,謝謝合作,
https://blog.csdn.net/DarianMograine/article/details/108562035
日前,筆者在優化資料庫PROCEDURE的程序中遇到這樣一個場景:
DECLARE
l_header_id NUMBER;
CURSOR cur_headers IS
SELECT col1
,col2
FROM table_a
WHERE 1 = 1
AND xxxx = xxxx;
CURSOR cur_lines(cp_col1 VARCHAR2
,cp_col2 VARCHAR2) IS
SELECT b.*
FROM table_b
WHERE col1 = cp_col1
AND col2 = cp_col2;
BEGIN
FOR rec IN cur_headers LOOP
l_header_id := xxx_headers_s.nextval;
INSERT INTO header_insert
(header_id, col1, col2)
VALUES
(l_header_id, rec.col1, rec.col2);
FOR line IN cur_lines(rec.col1, rec.col2) LOOP
INSERT INTO line_insert
(header_id, line_id, col3, col4, col5, col6)
VALUES
(l_header_id
,xxx_lines_s.nextval
,line.col3
,line.col4
,line.col5
,line.col6);
END LOOP;
END LOOP;
END;
這是一個非常典型的回圈遍歷以插入資料到資料庫表的程序,
在table_a和table_b的資料量暴增時程式的運行時間會急劇上升,
而針對這個問題,我們可以通過INSERT ALL來解決,
筆者在這里希望給大家一個建議,如果遇到這樣的場景,請按下面的方式來寫這段SQL,一段解決所有問題,讓你的代碼變得更優雅,
針對上面的代碼塊,我們可以用下面的代碼來代替,利用分析函式ROW_NUMBER來控制對頭表資料的插入:
DECLARE
FUNCTION get_hdr_seq RETURN NUMBER IS
RETURN xxx_headers_s.nextval;
END get_hdr_seq;
FUNCTION get_line_seq RETURN NUMBER IS
RETURN xxx_lines_s.nextval;
END get_line_seq;
BEGIN
INSERT ALL --
WHEN rn = 1 THEN --當是每個HEADER_ID的第一行時插入頭表一條資料
INTO header_insert
(header_id, col1, col2)
VALUES
(header_id, col1, col2) --
WHEN 1 = 1 THEN --
INTO line_insert
(header_id, line_id, col3, col4, col5, col6)
VALUES
(header_id, line_id, col3, col4, col5, col6)
SELECT h.header_id
,h.col1
,h.col2
,l.line_id
,l.col3
,l.col4
,l.col5
,l.col6
,row_number() over(PARTITION BY h.col1, h.col2 ORDER BY l.col3, l.col4) rn
FROM (SELECT get_hdr_seq header_id
,col1
,col2
FROM table_a h
WHERE xxxx = xxxx) h
,(SELECT get_line_seq line_id
,col1
,col2
,col3
,col4
,col5
,col6
FROM table_b l) l
WHERE h.col1 = l.col1
AND h.col2 = l.col2;
END;
以上,希望對大家有幫助,感興趣的同學可以一試,
原創文章,轉載請注明出處,謝謝合作,
https://blog.csdn.net/DarianMograine/article/details/108562035
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/38292.html
標籤:其他
下一篇:Android 11正式版發布!
