256
Как избежать подводных камней объектно-реляционного отображения
Листинг 13.9
Функция обновления
booking_leg
CREATE OR REPLACE FUNCTION booking_leg_update (
p_booking_leg_id int,
p_object json
)
RETURNS SETOF text
AS $body$
DECLARE
v_result booking_leg_record[];
v_sql text;
v_rec record;
v_flight_id int;
v_flight_each record;
v_booking_leg_update text;
BEGIN
FOR v_rec IN (SELECT * FROM json_each_text(p_object))
LOOP
CASE
WHEN v_rec.key = 'flight' THEN
FOR v_flight_each IN (
SELECT * FROM json_each_text(v_rec.value::json)
)
LOOP
CASE
WHEN v_flight_each.key = 'flight_id' THEN
v_flight_id := v_flight_each.value;
v_booking_leg_update := concat_ws(
', ', v_booking_leg_update,
'flight_id = ' || quote_literal(v_flight_each.value)
);
ELSE
NULL;
END CASE;
END LOOP;
WHEN v_rec.key IN ('leg_num', 'is_returning') THEN
v_booking_leg_update := concat_ws(
', ', v_booking_leg_update,
v_rec.key || '=' || quote_literal(v_rec.value)
);
ELSE
NULL;
END CASE;
END LOOP;
IF v_booking_leg_update IS NOT NULL THEN
EXECUTE ($$UPDATE booking_leg SET $$ || v_booking_leg_update ||
$$WHERE booking_leg_id = $$ || p_booking_leg_id::text);
END IF;
RETURN QUERY (
SELECT * FROM array_transport(booking_leg_select_json(p_booking_leg_id))
);
END;
$body$
LANGUAGE plpgsql;
Обновления
257
Первый параметр этой функции – идентификатор обновляемого сегмента
бронирования. Второй параметр – объект JSON, который функция интерпре-
тирует, чтобы определить, какие таблицы и поля следует обновить. Обратите
внимание, что независимо от того, какие ключи передаются в этом парамет-
ре, функция игнорирует все ключи, кроме тех, для которых мы указали алго-
ритм обработки. Например, хотя функция может получить все значения для
записи рейса, она обработает только идентификатор рейса
flight_id
, который
используется для обновления таблицы
booking_leg
. Хотя рейс – это вложенный
объект в сегменте бронирования, его нельзя обновить как часть бронирова-
ния; для обновления рейсов используется отдельная функция, а измененная
информация затем отобразится во всех зависимых бронированиях.
Например, выполним функцию вставки:
SELECT * FROM booking_leg_insert (
$${"leg_num":3,
"booking_id":232346,
"flight_id":13650,
"is_returning":"false"
}$$::json
)
Результатом будет новый сегмент бронирования:
Затем этот новый сегмент обновляется:
SELECT * FROM booking_leg_update (
17893568,
$${"flight":{"flight_id":13651,"flight_no":"1240"},
"is_returning":"true"
}$$
)
В результате будет показан обновленный сегмент бронирования:
Обратите внимание, что хотя в записи рейса и передается номер рейса
flight_no
, это значение игнорируется. Эта команда не меняет запись в таб-
лице
flight
; она меняет только идентификатор рейса в таблице
booking_leg
.
258
Как избежать подводных камней объектно-реляционного отображения
Мы также можем создать функцию для выдачи посадочного талона, анало-
гичную той, которая была создана в главе 11, но возвращающую новый тип
booking_leg_record
.
Do'stlaringiz bilan baham: |