В случае конфликта удалите postgres - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь переключить отношение в одном запросе, где оно удаляет отношение, если оно уже существует, в противном случае оно создает его. Я мог бы добавить третий столбец с bool, который переключает его, но я бы предпочел удалить его.

Схема

CREATE TABLE IF NOT EXISTS thread_subscription (
    profile_id     INTEGER REFERENCES profile (id),
    thread_id      INTEGER REFERENCES thread (id),
    UNIQUE(profile_id,thread_id)
)

Запрос

INSERT INTO thread_subscription (profile_id,thread_id) 
VALUES ($1,$2) ON CONFLICT (profile_id,thead_id) 
DO DELETE FROM thread_subscription 
WHERE profile_id = $1 AND thread_id = $2;

Ответы [ 2 ]

0 голосов
/ 08 января 2019

В дополнение к ответу GMB, вы можете избежать использования переменной с помощью PERFORM вместо использования SELECT .

CREATE OR REPLACE FUNCTION toggle_subscription(
    pid NUMERIC, 
    tid NUMERIC
) 
RETURNS NUMERIC AS $$

BEGIN

    perform FROM thread_subscription WHERE profile_id = pid and thread_id = tid;
    IF NOT FOUND THEN
        INSERT INTO thread_subscription(profile_id, thread_id) VALUES(pid, tid);
        RETURN 1;

    ELSE
         DELETE FROM thread_subscription WHERE profile_id = pid and thread_id = tid;
        RETURN 0;
    END IF;
END;     
$$
LANGUAGE plpgsql;

это скриптовая ссылка.

0 голосов
/ 08 января 2019

Таким образом, вы намереваетесь запустить заказ INSERT для таблицы, и вы ожидаете, что на дублирующих ключах это будет на самом деле DELETE связанная запись. Хотя это технически осуществимо, я бы не рекомендовал эту настройку, потому что это действие на расстоянии , которое трудно отладить.

Функциональность такого же типа, однако, может быть достигнута с помощью функции Postgres. Это делает намерение явным, когда речь идет о переключении подписки, и не мешает стандартным операторам базы данных (INSERT).

Вот код для функции: она принимает два параметра в качестве входных данных, проверяет, есть ли уже запись в таблице подписок, и затем выполняет соответствующую операцию; он возвращает 0 на DELETE и 1 на INSERT. Вы можете увидеть эту скрипку БД для полной демонстрации того, как она работает.

CREATE OR REPLACE FUNCTION toggle_subscription(
    pid NUMERIC, 
    tid NUMERIC
) 
RETURNS NUMERIC AS $$
DECLARE
    row_exists NUMERIC;
BEGIN

    SELECT 1 
    INTO row_exists 
    FROM thread_subscription 
    WHERE profile_id = pid and thread_id = tid;

    IF (row_exists > 0) THEN
        DELETE FROM thread_subscription WHERE profile_id = pid and thread_id = tid;
        RETURN 0;
    ELSE
        INSERT INTO thread_subscription(profile_id, thread_id) VALUES(pid, tid);
        RETURN 1;
    END IF;

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