patternsqlMinor
Constraint in ON CONFLICT clause has no associated index
Viewed 0 times
constrainthasassociatedconflictindexclause
Problem
I have this simple setup using PostgreSQL 13, latest dockerized:
When I launch the following sentence
I get
I know I'm inserting an stop id that is not included in the
How can I do it without having to manually check the result of the query? Is there anyway to do it with the SQL sentence?
CREATE TABLE stop (
id INT UNIQUE,
name TEXT,
PRIMARY KEY(id)
);
CREATE TABLE line (
id INT UNIQUE,
name TEXT,
PRIMARY KEY(id)
);
CREATE TABLE line_stops_sequence(
id SERIAL PRIMARY KEY,
line INT,
stop INT,
CONSTRAINT fk_line FOREIGN KEY(line) REFERENCES line(id),
CONSTRAINT fk_stop FOREIGN KEY(stop) REFERENCES stop(id)
);When I launch the following sentence
INSERT INTO line(id, name) VALUES (1, 'Line 1');
INSERT INTO stop(id, name) VALUES (2, 'Stop 2');
INSERT INTO line_stops_sequence(line, stop) VALUES (1,1), (1,2) ON CONFLICT ON CONSTRAINT fk_stop DO NOTHING;I get
constraint in ON CONFLICT clause has no associated index;I know I'm inserting an stop id that is not included in the
stop table. The idea is that I want to ignore the INSERTs that have conflicts. In the example it is just two items, but I'm inserting bulk data.How can I do it without having to manually check the result of the query? Is there anyway to do it with the SQL sentence?
Solution
The
You can ignore invalid references by incorporating checks into your insert statement, although you will need to switch from
ON CONFLICT clause is strictly for handling unique violation and exclusion constraint violation errors, as documented in the manual. There is no similar syntax allowing you to handle foreign key violation errors.You can ignore invalid references by incorporating checks into your insert statement, although you will need to switch from
INSERT...VALUES to INSERT...SELECT to be able to do that. Here is one way:INSERT INTO
line_stops_sequence(line, stop)
SELECT
new.line, new.stop
FROM
(VALUES (1,1), (1,2)) AS new (line, stop)
WHERE
new.line IN (SELECT id FROM line)
AND
new.stop IN (SELECT id FROM stop)
;Code Snippets
INSERT INTO
line_stops_sequence(line, stop)
SELECT
new.line, new.stop
FROM
(VALUES (1,1), (1,2)) AS new (line, stop)
WHERE
new.line IN (SELECT id FROM line)
AND
new.stop IN (SELECT id FROM stop)
;Context
StackExchange Database Administrators Q#294026, answer score: 8
Revisions (0)
No revisions yet.