Правильное использование Postgres JSON функций преобразования - PullRequest
0 голосов
/ 23 марта 2020

Я работаю над Postgres транзакцией обновления.

Допустим, у меня есть две таблицы: events и ticket_books с типами бронирования событий. Таблица ticket_books имеет внешний ключ, указывающий на events.

. Мне нужно обновить событие, хранящееся в базе данных, включая записи типа бронирования из таблицы ticket_books.

Для сделки с помощью каскадного обновления и удаления я решил построить транзакцию, в «псевдокоде» это выглядит так:

    BEGIN;
      DELETE FROM
        ticket_books
      WHERE
        event_id = ${req.params.id} AND
        id NOT IN (${bookingIds})
      FOR booking IN json_to_recordset('${JSON.stringify(book)}') as book(id int, title varchar(200), price int, ...) LOOP
        IF bookind.id THEN
          UPDATE
            ticket_books
          SET
            title = booking.title, price = booking.price
          WHERE
            event_id = ${req.params.id};
        ELSE
          INSERT INTO
            ticket_books (title, price, qty_available, qty_per_sale)
          VALUES
            (booking.title, booking.price, booking.qty_available, booking.qty_per_sale)
          RETURNING
            id
        END IF;
      END LOOP;
   UPDATE
     event
   SET
    ...
   WHERE
     id = ...
   RETURNING
     id;
   COMMIT;

В настоящее время я получаю сообщение об ошибке: syntax error at or near "json_to_recordset". Я никогда не пользовался json_to_recordset или друзьями раньше, только видел из документа, что с 9.3 и позже они доступны. Не знаю, как заставить Postgres понять, что мне нужно.

Я встраиваю массив JSON, поэтому последняя строка выглядит так:

FOR booking IN json_to_record('[{"id":13,"description":"Three day access to the festival","title":"Three Day General Admission","price":260,"qty_available":5000,"qty_per_sale":10},{"id":14,"description":"Single day access to the festival","title":"Single Day General Admission","price":"90.90","qty_available":2000,"qty_per_sale":2},{"title":"Free Admission","price":"0.00","qty_available":0,"qty_per_sale":0}]')

Я считаю, что мой JSON массив действителен. По-видимому, это не то, как я должен передавать его на Postgres. Что я должен делать вместо этого? Моя цель - перебрать записи массива. Если для booking.id есть целочисленное значение, я хочу обновить запись, иначе вставить новую.

1 Ответ

1 голос
/ 23 марта 2020

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

FOR booking IN select * from json_to_recordset(...

Кроме того, вы не можете использовать BEGIN для запуска транзакции в plpg sql. Он используется только для начала блока. Если вы используете процедуру, а не функцию, вы можете выполнить COMMIT, но тогда новая транзакция начнется немедленно, без использования токена BEGIN.

Вам также не хватает точки с запятой между DELETE и FOR, но из сообщения об ошибке, которое, по-видимому, отсутствует только в вашем сообщении, а не в фактическом коде.

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