J'écris un travail pour transformer les données d'une ancienne conception en une nouvelle conception. Dans ce processus, je dois prendre l'ID d'une insertion dans une table distincte et l'utiliser dans une insertion vers la table cible, en tant que telle:
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
};
J'ai le SQL défini qui correspond au formulaire suivant:
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;
Je voulais que cela exécute le SELECT * FROM ins
pour chaque ligne de la SELECT
.. mais à la place, il ne l'exécute qu'une seule fois et utilise cette valeur pour toutes les lignes de la SELECT
. Comment puis-je restructurer mon SQL pour obtenir le comportement souhaité?
edit4
t1 finit par ressembler à:
1,<NULL>
(1 row)
t2 finit par ressembler à:
10,'a',1
11,'b',1 -- problem with id from t1 being 1
12,'c',1 -- problem with id from t1 being 1
.
.
À quoi je veux que t1 ressemble:
1,<NULL>
2,<NULL>
3,<NULL>
.
.
À quoi je veux que t2 ressemble:
10,'a',1
11,'b',2 -- id from t1 of 2
12,'c',3 -- id from t1 of 3
.
.
modifier Pour répondre à ce qu'a dit a_horse_with_no_name, j'ai également essayé ceci (avec le même résultat):
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
J'ai juste essayé de référencer directement le approprié SEQUENCE
dans ma requête, et cela fonctionne - mais je n'aime pas du tout cette solution (principalement parce que je n'aime pas les noms d'objets codés en dur.) S'il existe une solution autre que de référencer directement le nom du SEQUENCE
je l'apprécierais. :)
edit3
Je suppose qu'une autre solution serait d'utiliser un PROCEDURE
pour faire le INSERT
au lieu d'un CTE .. mais j'apprécierais toujours les options / suggestions.
la source
ins
ett3
t1
et ne fournissez aucune valeur pourt1.col1
. D'où les données doivent-elles provenir pour cette colonne? Estt1.col1
lié àt2.col1
?INSERT INTO t1 (t1_id) VALUES (DEFAULT)
insère seulement 1 ligne danst1
. Donc, peu importe si vous mettezins
laFROM
clause dans la clause et que vous la joignezt3
ou non. Pouvez-vous nous montrer comment insérer 2 lignes (ou plus)t1
? Et plus important encore, comment savez-vous laquelle des 2 (ou plus)t1.id
valeurs correspondrait aux lignes insérées danst2
?Réponses:
Je ne comprends pas pourquoi vous avez besoin de 2 tables si elles n'ont qu'une relation 1-1. Mais le voici (
pk
c'est la clé primaire det3
):Si votre t3 est le résultat d'un SELECT au lieu d'une table préexistante, vous pouvez l'implémenter tel quel afin de ne pas avoir à répéter la requête t3 deux fois:
la source
t2_id
tout. Il semble que vous pouvez utiliser let2(t1_id)
comme PK det2
.ERROR: syntax error at or near "DEFAULT" LINE 2: DEFAULT AS contact_detail_id
DEFAULT
peut pas être utilisé de cette façon. Ni retour let.pk