Как вставлять массовые строки и игнорировать дубликаты в postgresql 9.3

У меня есть много строк данных, которые нужно вставить в таблицу. В таблице уже есть данные. Когда я делаю такую ​​массовую вставку,

INSERT INTO permission(username, permission) values(('john','ticket_view'), ('john','ticket_modify'), ('john','ticket_approve'));

Но в моей таблице уже есть строка john, ticket_view. В этом случае мой вышеупомянутый запрос на вставку завершается ошибкой duplicate key value violates unique constraint.

Как я могу игнорировать эту повторяющуюся проблему в postgresql 9.3? Я просто хочу вставить все строки. Если похожая строка существует, я хочу ее проигнорировать. Как я могу это сделать? Я приветствую вашу помощь.


person Velu narasimman    schedule 11.12.2018    source источник
comment
Postgres 9.3 длиннее, поддерживается. Если вы обновитесь до последней версии (например, 11 ) вы можете легко использовать функцию on conflict, представленную в 9.5   -  person a_horse_with_no_name    schedule 11.12.2018
comment
@a_horse_with_no_name, если я обновлю свой postgres до последней версии, как мне написать синтаксис ON CONFLICT для массовых вставок, как я сказал в моем вопросе? вы можете дать мне образец синтаксиса?   -  person Velu narasimman    schedule 11.12.2018
comment
Пожалуйста, прочтите повторяющиеся вопросы. Все они отвечают на ваш вопрос (включая решения для вашей устаревшей версии)   -  person a_horse_with_no_name    schedule 11.12.2018
comment
Вопросы, упомянутые как дубликаты, на самом деле не дублируют этот вопрос. OP хочет вставлять строки и игнорировать, а не обновлять, и его не интересует конкретно какой-либо синтаксис Postgres для вставки игнорирования / обновления, он просто хочет получить строки. Это действительно более похоже на вопрос к этому: stackoverflow.com/questions/47541579/ - см. мой ответ там, чтобы узнать простой способ сделать это в Postgres 9.3.   -  person nzn    schedule 07.04.2020


Ответы (1)


Предполагая, что вы используете Postgres 9.5 или выше, вы можете попробовать использовать ON CONFLICT, а также перефразировать свою вставку как INSERT INTO ... SELECT:

INSERT INTO permission (username, permission)
SELECT 'John', 'ticket_view' UNION ALL
SELECT 'John', 'ticket_modify' UNION ALL
SELECT 'John', 'ticket_approve'
ON CONFLICT (username, permission) DO NOTHING;

Если вы не можете использовать вышеуказанное решение, потому что у вас слишком много данных, тогда одним из вариантов будет сначала вставить ваши кортежи во временную таблицу, а затем использовать вышеуказанный запрос, например

CREATE TEMPORARY TABLE temp_permission (
    username VARCHAR NOT NULL,
    permission VARCHAR NOT NULL
)

INSERT INTO temp_permission (username, permission)
VALUES
    (('John', 'ticket_view'),
     ('John', 'ticket_modify'),
     ('John', 'ticket_approve'));

Затем используйте следующий запрос для вставки, игнорируя дубликаты:

INSERT INTO permission (username, permission)
SELECT username, permission
FROM temp_permission
ON CONFLICT (username, permission) DO NOTHING;

После этого вы можете опустить временную таблицу.

person Tim Biegeleisen    schedule 11.12.2018
comment
В вопросе прямо говорится о PG 9.3. - person 404; 11.12.2018
comment
@ 404 Нет особенно хорошего способа сделать это в ‹9.5. Может быть, мой ответ все же будет полезен. - person Tim Biegeleisen; 11.12.2018
comment
@TimBiegeleisen, мне нравится ваш ответ, но значения, которые я передаю, являются некоторыми динамическими данными, поэтому я могу явно писать select утверждения, как вы сказали. Как я могу добиться того же для таких динамических данных? - person Velu narasimman; 11.12.2018
comment
Сначала вставьте свой VALUES во временную таблицу, а затем используйте мой ответ. - person Tim Biegeleisen; 11.12.2018
comment
@TimBiegeleisen, я обновил postgres до версии 11. и использовал значения разрешения INSERT INTO (имя пользователя, разрешение) (('john', 'ticket_view'), ('john', 'ticket_modify'), ('john', ' ticket_approve ')) НА КОНФЛИКТЕ НИЧЕГО НЕ ДЕЛАЙТЕ; теперь я получаю эту ошибку: "Синтаксическая ошибка на или почти". Я много борюсь, но не понимаю, почему это останавливает запрос! пожалуйста, помогите мне! - person Velu narasimman; 11.12.2018
comment
Думаю, ваш запрос не сработает. Взгляните на мой обновленный ответ. - person Tim Biegeleisen; 11.12.2018