Как предотвратить повторную вставку с возвратом вставки в postgres? - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь создать некоторые правила для моей БД, чтобы предотвратить повторяющиеся вставки, но, поскольку мы также в спящем режиме, .save () называется insert xxx RETURNING *

Кажется, я не могузаставить правило вставки хорошо играть с возвращаемой вставкой.

CREATE TABLE test ( aaa int, bbb int);

insert into test VALUES(1, 2);

CREATE RULE "testRule1" AS ON INSERT TO  test
  WHERE EXISTS(SELECT 1 FROM test 
                WHERE (aaa, bbb)=(NEW.aaa, NEW.bbb))
  DO INSTEAD NOTHING;

Если я пытаюсь вставить только с одним условным правилом

insert into test VALUES(1, 2);
ERROR:  cannot perform INSERT RETURNING on relation "test"
HINT:  You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause.

CREATE RULE "testRule2" AS ON INSERT TO  test
  DO INSTEAD INSERT INTO test VALUES(new.*)
  RETURNING test.*;

Если я пытаюсь вставить с условными и безусловными правилами

insert into test VALUES(1, 2);
ERROR:  infinite recursion detected in rules for relation "test"

Этого невозможно достичь с помощью моей установки?

1 Ответ

0 голосов
/ 06 февраля 2019

Правильный способ избежать вставки дубликатов - определить поля как UNIQUE (или PRIMARY KEY)

CREATE TABLE Test (
aaa integer,
bbb integer,
val text, /* The reason why I added this field is explained later */
UNIQUE (aaa,bbb)
)

Вставка завершится неудачно с кодом ошибки, если кортеж уже существует (получение кодов ошибок)из базы данных - это хорошо, как я недавно объяснил здесь ).

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

INSERT INTO Test values (1,1,'Some value')
ON CONFLICT DO NOTHING

В основном будет вставлена ​​первая запись с уникальным кортежем.Это совместимо, даже если сам запрос пытается вставить дубликаты, как в случае ниже:

INSERT INTO Test values (2,2,'Will be inserted'), (2,2,'Will not be inserted')
ON CONFLICT DO NOTHING

Конечно, это также позволит вам иметь предложение RETURNING в том же запросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...