我有一个pl sql过程,该过程接受元素数组并将其插入表中。
在此过程的开始,我要从备份表中删除数据,并将主表中的数据插入备份表中。然后我要从主表中删除数据,并遍历proc的参数并插入记录。当我面对dup_val_on_index exception
时,回滚正发生在proc的起点。我的意思是异常块正在执行。但是回滚没有发生。
例如,如果我插入2个具有重复值的行,则必须引发dup_val_on_index exception
并且不应插入第一行。
下面是我的代码。如果循环内发生任何异常,我也想回滚插入并在过程开始时执行删除操作
PROCEDURE insert_sales_data (
p_depot_code IN depotcode_array,
p_depot_name IN depotname_array,
p_dell_split IN dellsplit_array,
p_sector IN sector_array,
p_locality IN locality_array,
p_tnt_depot_code IN tntdepotcode_array,
p_postal_code IN postalcode_array,
p_primary_sort IN primarysort_array,
p_secondary_sort IN secondarysort_array,
p_user IN VARCHAR2,
p_error_message OUT VARCHAR2,
p_count OUT NUMBER
)
IS
BEGIN
SAVEPOINT s1;
DELETE FROM sales_backup;
INSERT INTO sales_backup
SELECT
*
FROM
sales;
DELETE FROM sales;
FOR i IN p_sector.first..p_sector.last LOOP
BEGIN
INSERT INTO sales (
depot_code,
depot_name,
dell_split,
sector,
locality,
tnt_depot_code,
postal_code,
primary_sort,
secondary_sort,
create_date,
create_user_id,
uuid
) VALUES (
p_depot_code(i),
p_depot_name(i),
p_dell_split(i),
p_sector(i),
p_locality(i),
p_tnt_depot_code(i),
p_postal_code(i),
p_primary_sort(i),
p_secondary_sort(i),
SYSDATE,
p_user,
sys_guid()
);
EXCEPTION
WHEN dup_val_on_index THEN
ROLLBACK TO s1;
EXIT;
WHEN OTHERS THEN
ROLLBACK TO s1;
EXIT;
END;
END LOOP;
SELECT
COUNT(*)
INTO p_count
FROM
uk_depots;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO s1;
END;
答案 0 :(得分:0)
希望,我正确理解了您的问题。请尝试使用以下代码块。
PROCEDURE insert_sales_data (
p_depot_code IN depotcode_array,
p_depot_name IN depotname_array,
p_dell_split IN dellsplit_array,
p_sector IN sector_array,
p_locality IN locality_array,
p_tnt_depot_code IN tntdepotcode_array,
p_postal_code IN postalcode_array,
p_primary_sort IN primarysort_array,
p_secondary_sort IN secondarysort_array,
p_user IN VARCHAR2,
p_error_message OUT VARCHAR2,
p_count OUT NUMBER
)
IS
BEGIN
DELETE FROM sales_backup;
INSERT INTO sales_backup
SELECT
*
FROM
sales;
DELETE FROM sales;
FOR i IN p_sector.first..p_sector.last LOOP
BEGIN
INSERT INTO sales (
depot_code,
depot_name,
dell_split,
sector,
locality,
tnt_depot_code,
postal_code,
primary_sort,
secondary_sort,
create_date,
create_user_id,
uuid
) VALUES (
p_depot_code(i),
p_depot_name(i),
p_dell_split(i),
p_sector(i),
p_locality(i),
p_tnt_depot_code(i),
p_postal_code(i),
p_primary_sort(i),
p_secondary_sort(i),
SYSDATE,
p_user,
sys_guid()
);
EXCEPTION
WHEN dup_val_on_index THEN
ROLLBACK;
EXIT;
WHEN OTHERS THEN
ROLLBACK;
EXIT;
END;
END LOOP;
SELECT
COUNT(*)
INTO p_count
FROM
uk_depots;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
答案 1 :(得分:0)
从我对您的问题的理解来看,它应该更简单:
PROCEDURE insert_sales_data (
p_depot_code IN depotcode_array,
p_depot_name IN depotname_array,
p_dell_split IN dellsplit_array,
p_sector IN sector_array,
p_locality IN locality_array,
p_tnt_depot_code IN tntdepotcode_array,
p_postal_code IN postalcode_array,
p_primary_sort IN primarysort_array,
p_secondary_sort IN secondarysort_array,
p_user IN VARCHAR2,
p_error_message OUT VARCHAR2,
p_count OUT NUMBER
)
IS
BEGIN
SAVEPOINT s1;
DELETE FROM sales_backup;
INSERT INTO sales_backup
SELECT
*
FROM
sales;
DELETE FROM sales;
FOR i IN p_sector.first..p_sector.last LOOP
INSERT INTO sales (
depot_code,
depot_name,
dell_split,
sector,
locality,
tnt_depot_code,
postal_code,
primary_sort,
secondary_sort,
create_date,
create_user_id,
uuid
) VALUES (
p_depot_code(i),
p_depot_name(i),
p_dell_split(i),
p_sector(i),
p_locality(i),
p_tnt_depot_code(i),
p_postal_code(i),
p_primary_sort(i),
p_secondary_sort(i),
SYSDATE,
p_user,
sys_guid()
);
END LOOP;
SELECT
COUNT(*)
INTO p_count
FROM
uk_depots;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO s1;
END;
该块是完全没有用的,无论遇到哪个错误,您都将执行回滚。
EXCEPTION
WHEN dup_val_on_index THEN
ROLLBACK TO s1;
EXIT;
WHEN OTHERS THEN
ROLLBACK TO s1;
EXIT;
END;