Estou escrevendo um trabalho para transformar dados de um design antigo em um novo design. Nesse processo, preciso levar o ID de uma inserção para uma tabela separada e usá-lo em uma inserção para a tabela de destino, como tal:
CREATE TABLE t1 {
t1_id BIGSERIAL,
col1 VARCHAR
};
CREATE TABLE t2 {
t2_id BIGSERIAL,
col2 VARCHAR, -- renamed from col1 to avoid confusion
t1_id BIGINT REFERENCES t1.t1_id
};
Eu tenho o SQL definido que corresponde ao seguinte formulário:
WITH ins AS (
INSERT INTO t1 (t1_id) VALUES (DEFAULT) RETURNING t1_id
) INSERT INTO t2
(col1, t1_id)
SELECT
a.val1, (SELECT * FROM ins)
FROM t3 a;
Eu queria que isso executasse o SELECT * FROM ins
para todas as linhas do SELECT
.. mas, em vez disso, ele é executado apenas uma vez e usa esse valor para todas as linhas no SELECT
. Como posso reestruturar meu SQL para obter o comportamento desejado?
edit4
t1 acaba assim:
1,<NULL>
(1 row)
t2 acaba assim:
10,'a',1
11,'b',1 -- problem with id from t1 being 1
12,'c',1 -- problem with id from t1 being 1
.
.
Como eu quero que o t1 seja:
1,<NULL>
2,<NULL>
3,<NULL>
.
.
Como eu quero que o t2 seja:
10,'a',1
11,'b',2 -- id from t1 of 2
12,'c',3 -- id from t1 of 3
.
.
edit Para abordar o que a_horse_with_no_name disse, eu também tentei isso (com o mesmo resultado):
WITH ins AS (
INSERT INTO t1 (t1_id) VALUES (DEFAULT) RETURNING t1_id
) INSERT INTO t2
(col1, t1_id)
SELECT
a.val1, b.t1_id
FROM t3 a
JOIN ins b ON TRUE;
edit2
Eu apenas tentei fazer referência direta ao apropriado SEQUENCE
na minha consulta e isso funciona - mas não gosto muito dessa solução (principalmente porque não gosto de nomes de objetos codificados). Se houver QUALQUER outra solução do que referenciar diretamente o nome do que SEQUENCE
eu apreciaria. :)
edit3
Suponho que outra solução seria fazer uso de a PROCEDURE
para fazer o INSERT
CTE, em vez de ... mas ainda assim eu apreciaria opções / sugestões.
t1
e não está fornecendo nenhum valor t1.col1
. Onde os dados devem chegar para essa coluna? Está t1.col1
relacionado com t2.col1
?
INSERT INTO t1 (t1_id) VALUES (DEFAULT)
insere apenas 1 linha t1
. Portanto, não importa se você coloca ins
a FROM
cláusula na e a junta t3
ou não. Você pode nos mostrar como inserir 2 (ou mais) linhas t1
? E mais importante, como você sabe em qual dos 2 (ou mais) t1.id
valores corresponderia as linhas inseridas t2
?
ins
et3