J'ai un tas de lignes que je dois insérer dans la table, mais ces insertions sont toujours effectuées par lots. Je veux donc vérifier si une seule ligne du lot existe dans la table car je sais qu’elles ont toutes été insérées.
Donc, ce n'est pas une vérification de clé primaire, mais ne devrait pas avoir trop d'importance. Je voudrais seulement vérifier une seule ligne pour que count(*)
ne soit probablement pas bon, alors c'est quelque chose comme exists
je suppose.
Mais comme je suis assez nouveau pour PostgreSQL, je préférerais demander à ceux qui savent.
Mon lot contient des lignes avec la structure suivante:
userid | rightid | remaining_count
Donc, si la table contient des lignes avec userid
fourni, cela signifie qu'elles y sont toutes présentes.
Utilisez la clé EXISTS Word pour un retour VRAI/FAUX:
select exists(select 1 from contact where id=12)
Que diriez-vous simplement:
select 1 from tbl where userid = 123 limit 1;
où 123
est l'ID utilisateur du lot que vous êtes sur le point d'insérer.
La requête ci-dessus renvoie soit un ensemble vide, soit une seule ligne, selon qu'il existe ou non des enregistrements avec l'ID utilisateur indiqué.
Si cela s'avère trop lent, vous pouvez envisager de créer un index sur tbl.userid
.
si même une seule ligne de lot existe dans la table, dans ce cas, je n'ai pas à insérer mes lignes car je sais qu'elles ont toutes été insérées.
Pour que cela reste vrai même si votre programme est interrompu en cours de lot, nous vous recommandons de vous assurer de gérer les transactions de base de données correctement (c'est-à-dire que l'intégralité du lot est insérée dans une seule transaction).
INSERT INTO target( userid, rightid, count )
SELECT userid, rightid, count
FROM batch
WHERE NOT EXISTS (
SELECT * FROM target t2, batch b2
WHERE t2.userid = b2.userid
-- ... other keyfields ...
)
;
BTW: si vous voulez le tout le lot échoue en cas de duplication, alors (avec une contrainte de clé primaire)
INSERT INTO target( userid, rightid, count )
SELECT userid, rightid, count
FROM batch
;
fera exactement ce que vous voulez: soit cela réussit, soit cela échoue.
select true from tablename where condition limit 1;
Je crois que c’est la requête que postgres utilise pour vérifier les clés étrangères.
Dans votre cas, vous pouvez le faire en une fois aussi:
insert into yourtable select $userid, $rightid, $count where not (select true from yourtable where userid = $userid limit 1);
Règle de base
select existe (sélectionnez true parmi xx où xx) en tant que "Est-ce que 1 + 1 ajoute jusqu'à 2";
comme l'a souligné @MikeM.
select exists(select 1 from contact where id=12)
avec index au contact, cela permet généralement de réduire le coût en temps à 1 ms.
CREATE INDEX index_contact on contact(id);
Si vous pensez à la performance, vous pouvez peut-être utiliser "PERFORM" dans une fonction comme celle-ci:
PERFORM 1 FROM skytf.test_2 WHERE id=i LIMIT 1;
IF FOUND THEN
RAISE NOTICE ' found record id=%', i;
ELSE
RAISE NOTICE ' not found record id=%', i;
END IF;
SELECT 1 FROM user_right where userid = ? LIMIT 1
Si votre jeu de résultats contient une ligne, vous n'avez pas à l'insérer. Sinon, insérez vos enregistrements.