The 23505
error code in PostgreSQL, unique_violation
, occurs when an operation, typically an INSERT
or UPDATE
, violates a unique constraint defined in your database. This could be a primary key or any other unique index. To resolve this error, you must ensure that the data you are trying to insert or update is unique according to the constraints defined in your table schema.
Example 1: Inserting Duplicate Primary Key
Attempting to insert a row with a primary key that already exists in the table will result in a unique_violation
error.
-- Assuming you have a table with a primary key column 'id'
CREATE TABLE my_table (id SERIAL PRIMARY KEY, name TEXT);
-- Insert a row
INSERT INTO my_table (name) VALUES ('John Doe');
-- Incorrect way that causes error 23505
INSERT INTO my_table (id, name) VALUES (1, 'Jane Smith');
-- Correct way
-- Omit the primary key in the INSERT statement to let SERIAL work
INSERT INTO my_table (name) VALUES ('Jane Smith');
Example 2: Violating a Unique Index
Creating a unique index on a column and then trying to insert a duplicate value will trigger the unique_violation
error.
-- Assuming 'email' should be unique
CREATE UNIQUE INDEX unique_email_idx ON my_table (email);
-- Incorrect way that causes error 23505
INSERT INTO my_table (email, name) VALUES ('john@example.com', 'John Doe');
-- Correct way
-- Before inserting, check if the email already exists
INSERT INTO my_table (email, name)
SELECT 'jane@example.com', 'Jane Smith' WHERE NOT EXISTS (
SELECT 1 FROM my_table WHERE email = 'jane@example.com'
);
Example 3: Updating a Row to a Duplicate Unique Key
Trying to update a row to have a value that already exists in another row for a column with a unique constraint will also lead to a unique_violation
error.
-- Incorrect way that causes error 23505
UPDATE my_table SET email = 'john@example.com' WHERE id = 2;
-- Correct way
-- Check that the new value does not exist before updating
UPDATE my_table
SET email = 'jane@example.com'
WHERE id = 2 AND NOT EXISTS (
SELECT 1 FROM my_table WHERE email = 'jane@example.com'
);
Example 4: Concurrent Inserts
When multiple transactions are trying to insert data concurrently, you might get a unique_violation
even if you checked for the existence of the value before inserting.
-- Correct way with additional handling for concurrency
-- Use a transaction with appropriate isolation level or retry logic
BEGIN;
INSERT INTO my_table (email, name)
SELECT 'john@example.com', 'John Doe' WHERE NOT EXISTS (
SELECT 1 FROM my_table WHERE email = 'john@example.com'
);
-- Handle unique_violation exception if necessary
COMMIT;
To handle the 23505
error code properly, you may also want to implement error handling in your application code to catch the exception and respond accordingly, such as prompting the user to provide a different unique value.
For more details on error handling and unique constraints in PostgreSQL, you can refer to the official documentation on PostgreSQL Error Codes and constraint management. There are also community resources like Stack Overflow where you can find discussions and solutions related to handling unique_violation
errors.