Eu tenho três tabelas, que crio com essas consultas:
create table parents(
rowid serial primary key,
display_name varchar,
unique(display_name)
);
create table clients(
rowid serial primary key,
parent int,
display_name varchar,
foreign key (parent) references parents(rowid),
unique(display_name, parent)
);
create table datapoints(
rowid serial primary key,
client int,
val float8,
foreign key (client) references clients(rowid)
);
Estou recebendo dados que contêm nome do pai, nome do cliente e algum valor. Cada vez que recebo esses dados, quero adicionar linhas à tabela de pontos de dados. Também quero adicionar linhas à tabela de clientes e pais, mas somente se os dados que recebi tiverem nomes não reconhecidos.
Por exemplo, eu poderia obter estes dados:
"pai1-cliente1-123.0"
O que eu gostaria de conseguir é processar esses dados (em uma consulta), desta forma:
Insira uma linha na tabela "pais", se necessário.
Insira uma linha na tabela "clientes" com o ID pai apropriado (obtido na etapa anterior?), se necessário.
Insira uma linha na tabela "datapoints" com o ID do cliente apropriado (obtido na etapa anterior?).
Como posso gerenciar isso com consultas? O programador em mim quer escrever:
- Insira nos pais, se necessário. Salve o id do pai apropriado em uma variável "current_parent"
- Insira nos clientes, se necessário, usando a variável "current_parent". Salve o id do cliente apropriado em uma variável "current_client".
- Insira em pontos de dados, usando a variável "current_client" do arquivo anterior. degrau.
Mas obviamente não é assim que o sql funciona, certo? E se, em vez dessas três tabelas "aninhadas" eu tiver 5 ou 10?(!)
Por favor ajude
Essa é uma aplicação trivial de
INSERT ... RETURNING
:Então você pode usar o valor retornado para o próximo
INSERT
.Você pode fazer todas as três inserções em uma única instrução SQL usando CTEs: