There’s a table:
create table mytab(
r char(38) not null,
h char(2),
p bytea not null,
primary key (r,h)
)
I’m inserting hundreds of rows at once, like this:
insert into mytab (r, h, p) values
('val_r', 'a0', 'pr_1'), ('r1', 'a1', 'p1')......
I need to replace the regular insert
with a "smart" one:
- if there’re no such keys
(r,h)
then insert the row - if the keys exist and the value (
p
) is the same as new then do nothing - if the keys exist but the value is different – throw an error for this particular row only, somehow let the app know that this particular row has error – and continue with other rows
I’ve read about insert ... on conflict do update/nothing
but it looks like it’s not applicable esp. because of rule 3, in docs I found nothing like "do fail".
So, how can I do it, inserting many rows at once? Maybe something like stored procedure, but how?
PgSQL 15, psycopg2. Using insert
one row at a time is not an option due to performance penalty.
2
Answers
Maybe create a procedure with a out parameter and use cursor to select rows from the table and loop through each row. Check within the table mytab if there exists any record with r, h like this.
This is the cursor code only not the procedure.
Here I have used p_out which will be the out parameter for the stored procedure.
Initially insert all records in the temp_table.
upon calling the procedure the out parameter will provide the output with the details of failing rows on each line.
Create a trigger for the table.
The trigger function filters inserted rows and reports incorrect ones as a notice, or channel notification, or in a special table (your choice).
Test it in db<>fiddle.