[plsql] Allow error logging for multi-inserts

Refs #2779
This commit is contained in:
Andreas Dangel 2024-06-13 10:36:53 +02:00
parent e0d465a81b
commit 3c34431cb8
No known key found for this signature in database
GPG Key ID: 93450DF2DF9A3FA3
3 changed files with 497 additions and 12 deletions

View File

@ -2508,7 +2508,7 @@ ASTInsertIntoClause InsertIntoClause() :
{}
{
<INTO> DMLTableExpressionClause()
[ LOOKAHEAD(2) TableAlias() ]
[ LOOKAHEAD(2, {!getToken(1).getImage().equalsIgnoreCase("LOG")}) TableAlias() ]
[
LOOKAHEAD(2) "("
[ LOOKAHEAD(2) TableName() "." ] Column()
@ -2533,18 +2533,19 @@ ASTMultiTableInsert MultiTableInsert() :
{}
{
(
LOOKAHEAD(2) <ALL> ( InsertIntoClause() [ ValuesClause() ] )+ Subquery()
LOOKAHEAD(2) <ALL> ( InsertIntoClause() [ ValuesClause() ] [ ErrorLoggingClause() ] )+
|
ConditionalInsertClause()
)
Subquery()
{ return jjtThis; }
}
ASTConditionalInsertClause ConditionalInsertClause() :
{}
{
[ <ALL> | KEYWORD("FIRST") ] ( <WHEN> Condition() <THEN> ( InsertIntoClause() [ ValuesClause() ] )+ )+
[ <ELSE> ( InsertIntoClause() [ ValuesClause() ] )+ ]
[ <ALL> | KEYWORD("FIRST") ] ( <WHEN> Condition() <THEN> ( InsertIntoClause() [ ValuesClause() ] [ ErrorLoggingClause() ] )+ )+
[ <ELSE> ( InsertIntoClause() [ ValuesClause() ] [ ErrorLoggingClause() ] )+ ]
{ return jjtThis; }
}

View File

@ -4,7 +4,6 @@
create or replace procedure test as
begin
-- https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/INSERT.html#GUID-903F8043-0254-4EE9-ACC1-CB8AC0AF3423__BCEGDJDJ
INSERT INTO raises
SELECT employee_id, salary*1.1 FROM employees
@ -25,5 +24,40 @@ begin
-- without a table alias
delete from test_table
log errors into err$_test_table reject limit unlimited;
-- https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/INSERT.html#GUID-903F8043-0254-4EE9-ACC1-CB8AC0AF3423__BCEGDJDJ
-- multi-insert with conditional and optional error logging
INSERT ALL
WHEN order_total <= 100000 THEN
INTO small_orders LOG ERRORS INTO errlog ('my_bad') REJECT LIMIT 10
WHEN order_total > 1000000 AND order_total <= 200000 THEN
INTO medium_orders LOG ERRORS INTO errlog ('my_bad') REJECT LIMIT 10
WHEN order_total > 200000 THEN
INTO large_orders
ELSE
INTO other_orders LOG ERRORS INTO errlog ('my_bad') REJECT LIMIT 10
SELECT order_id, order_total, sales_rep_id, customer_id
FROM orders;
-- multi-insert with optional error logging
INSERT ALL
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date, sales_sun)
LOG ERRORS INTO errlog ('my_bad') REJECT LIMIT 10
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+1, sales_mon)
LOG ERRORS INTO errlog ('my_bad') REJECT LIMIT 10
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+2, sales_tue)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+3, sales_wed)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+4, sales_thu)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+5, sales_fri)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+6, sales_sat)
SELECT product_id, customer_id, weekly_start_date, sales_sun,
sales_mon, sales_tue, sales_wed, sales_thu, sales_fri, sales_sat
FROM sales_input_table;
end;
/