В этом случае ответ ни .Ни провоцируйте ошибку, ни проверяйте заранее.Ну, в любом случае в основном .
С ним можно работать проще - и безопаснее, и быстрее:
INSERT INTO users(username, col1)
SELECT 'max', 'val1'
WHERE NOT EXISTS (SELECT * FROM users WHERE username = 'max')
Это добавит нового пользователя, только если он не существуетуже.PostgreSQL установит статус команды на 0 rows affected
или 1 row affected
, в зависимости от того, была ли она там уже.В любом случае, оно будет там после этого оператора.
Если вы хотите получить ответ:
INSERT INTO users(username, col1)
SELECT 'max', 'val1'
WHERE NOT EXISTS (SELECT * FROM users WHERE username = 'max')
RETURNING username;
Это вернет имя пользователя, только если оно еще не существовало.
Однакооперация не является атомарной, поэтому, если у вас много параллелизма, установите блокировку таблицы следующим образом:
BEGIN;
LOCK TABLE users IN SHARE MODE;
INSERT INTO users(username, col1)
SELECT 'max', 'val1'
WHERE NOT EXISTS (SELECT * FROM users WHERE username = 'max')
RETURNING username;
COMMIT;
Обратите внимание, что это все равно может завершиться ошибкой, даже если очень маловероятно - например, если другойтранзакция блокирует таблицу и блокирует вас навсегда из-за какой-то ошибки.
Итак, по общему признанию, вам все еще нужен код для обработки ошибки.Это никогда не должно происходить, если только у вашей базы данных или приложений нет проблем.