#postgresql #loops #sql-update #foreign-keys
#postgresql #циклы #sql-обновление #внешние ключи
Вопрос:
Я случайно удалил большинство строк в моей таблице Postgres (данные не важны в моей тестовой среде, но мне нужны фиктивные данные для вставки в эту таблицу).
Давайте возьмем три таблицы,
MAIN_TABLE(main_table_id, main_fields)
ADDRESS_TABLE(address_table_id, main_table_id, address_type, other_fielsds)
CHAID_TABLE(chaid_table_id,main_table_id, shipping_address_id, chaild_fields)
Я случайно удалил большую часть данных из ADDRESS_TABLE.
-
ADDRESS_TABLE имеет внешний ключ из MAIN_TABLE , т.е. main_table_id . для каждой строки в MAIN_TABLE в ADDRESS_TABLE есть две записи, в которых одна запись имеет свой address_type — «выставление счетов / по умолчанию», а другая запись — для address_type «доставка».
-
CHAID_TABLE имеет два внешних ключа, один из MAIN_TABLE, т.е. main_table_id, а другой из ADDRESS_TABLE, т.Е. shipping_address_id . этот shipping_address_id является идентификатором адреса ADDRESS_TABLE, его address_type — доставка, а ADDRESS_TABLE.main_table_id = CHAID_TABLE.main_table_id .
Это то, что мне было нужно.
- Мне нужно создать две фиктивные записи адресов для каждого raw в MAIN_TABLE, одна из которых имеет тип адреса «выставление счетов / по умолчанию», а другая — типа «доставка».
- Мне нужно вставить address_table_id в ТАБЛИЦУ CHAID_TABLE, чей ADDRESS_TABLE.main_table_id = CHAID_TABLE.main_table_id. и address_type =»доставка»
если первое выполнено, я знаю, как вставить второе, потому что это простой запрос на вставку. Я думаю. это можно сделать следующим образом,
UPDATE CHAID_TABLE
SET shipping_address_id = ADDRESS_TABLE.address_table_id
FROM ADDRESS_TABLE
WHERE ADDRESS_TABLE.main_table_id = CHAID_TABLE.main_table_id
AND ADDRESS_TABLE.addres_type ='shipping';
для выполнения первого я могу использовать цикл в psql, т.Е. перебирать все записи в MAIN_TABLE и вставлять две фиктивные строки для каждой строки. Но я не знаю, как это сделать, пожалуйста, помогите мне решить эту проблему.
Ответ №1:
Я надеюсь, что ваше решение таково: создайте функцию, которая перебирает все строки в MAIN_TABLE, внутри цикла выполните нужное действие, здесь два оператора insert, одна из проблем этого решения заключается в том, что у вас одинаковые данные по всем адресам.
CREATE OR REPLACE FUNCTION get_all_MAIN_TABLE () RETURNS SETOF MAIN_TABLE AS
$BODY$
DECLARE
r MAIN_TABLE %rowtype;
BEGIN
FOR r IN
SELECT * FROM MAIN_TABLE
LOOP
-- can do some processing here
INSERT INTO ADDRESS_TABLE ( main_table_id, address_type, other_fielsds)
VALUES('shipping', r.main_table_id,'NAME','','other_fielsds');
INSERT INTO ADDRESS_TABLE ( main_table_id, address_type, other_fielsds)
VALUES('billing/default',r.main_table_id,'NAME','','other_fielsds');
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql;
SELECT * FROM get_all_MAIN_TABLE ();