#sql #postgresql
Вопрос:
Это мои столы:
CREATE TABLE networks ( network_id SERIAL UNIQUE PRIMARY KEY, network_name TEXT NOT NULL UNIQUE ); CREATE TABLE addresses ( address_id SERIAL UNIQUE NOT NULL, network_id integer REFERENCES networks (network_id), address TEXT NOT NULL UNIQUE, PRIMARY KEY (address_id, network_id) );
Я пытаюсь вставить значение в networks
, а затем вставить автоматически сгенерированное network_id
в другую таблицу.
Этот запрос работает для значений, которые не существуют, networks
и выполняет то, что я ищу:
WITH par_key AS ( INSERT INTO networks (network_name) VALUES ('ethereum') RETURNING network_id ) INSERT INTO addresses (network_id, address) VALUES ( (select par_key.network_id from par_key), 'address1' )
Однако этот запрос приводит к повторяющейся ошибке:
WITH par_key AS ( INSERT INTO networks (network_name) VALUES ('ethereum') RETURNING network_id ) INSERT INTO addresses (network_id, address) VALUES ( (select par_key.network_id from par_key), 'address2' )
ERROR: duplicate key value violates unique constraint "networks_token_name_key" DETAIL: Key (network_name)=(ethereum) already exists.
Я бы хотел, чтобы запрос выполнялся addresses
с network_id
помощью, если значение уже существует networks
.
Изменить: пришлось переименовать token_name
в приведенной выше таблице в network_name
.
Ответ №1:
Вы можете сделать это с помощью двух запросов и повторять одну и ту же сеть с разными адресами столько раз, сколько потребуется.
insert into networks (token_name) VALUES ('ethereum') on conflict do nothing; insert into addresses (network_id, address) values ( (select network_id from networks where token_name = 'ethereum'), 'address2' );
Если вам нужен один запрос, используйте эту функцию SQL:
create or replace function the_function(arg_token text, arg_address text) returns bigint language sql as $ insert into networks (token_name) VALUES (arg_token) on conflict do nothing; insert into addresses (network_id, address) values ( (select network_id from networks where token_name = arg_token), arg_address ) returning network_id; $; -- Use as select the_function('ethereum', 'address1'); select the_function('ethereum', 'address2');
Комментарии:
1. Очень признателен, спасибо!
2. Принять ответ?