Avec types composites postgres vous pouvez essentiellement construire un champ avec la structure étant définie comme une autre table. J'ai le champ composite appelé "destinataire" de type "personne". Ce champ de destinataire est souvent laissé vide dans mon scénario spécifique. Quelle est la bonne façon de vérifier si un champ composite est vide. J'ai essayé:
select * from bla where recipient is not null
select * from bla where recipient is null
select * from bla where recipient = null
select * from bla where recipient != null
Dans tous ces cas, il ne renvoie rien. Alors, comment vérifiez-vous correctement si une valeur composite est vide ou non?
[~ # ~] mise à jour [~ # ~]
Après un peu plus de lecture, il semble que c'est mon problème:
On peut penser que
!(x IS NULL) = x IS NOT NULL
est vrai dans tous les cas. Mais il existe une exception - les types composites. Lorsqu'un champ d'une valeur composite estNULL
et qu'un autre champ estNOT NULL
, Le résultat des deux opérateurs est faux.IS NULL
Est vrai, uniquement lorsque tous les champs sontNULL
.IS NOT NULL
Est vrai, uniquement lorsque tous les champs sontNOT NULL
. Dans tous les cas intermédiaires, les deux opérateurs renvoient false.
J'ai certains champs qui sont nuls et d'autres qui ne le sont pas. J'espérais que le champ serait considéré comme NON NUL, si un élément du champ composite n'est pas nul ... pas quand TOUS ne le sont pas. Y a-t-il un moyen de contourner cela autre que de vérifier chaque champ?
IS NULL
et IS NOT NULL
fonctionne aussi pour les types complexes, donc ces deux devraient être appropriés:
select * from bla where recipient is not null
select * from bla where recipient is null
Pour intercepter les cas où pas tous les champs de la valeur composite (ligne/enregistrement) sont NULL:
SELECT *
FROM bla
WHERE NOT (recipient IS NULL);
<row-type> is NULL
renvoie uniquement TRUE
si tous les champs sont NULL
.<row-type> is NOT NULL
renvoie uniquement TRUE
si tous les champs sont NOT NULL
.
Les parenthèses sont facultatives. La priorité des opérateurs fonctionne de toute façon en notre faveur.
Démontrer les différentes options:
CREATE TEMP TABLE recipient (r text, i int); -- to register the row type
SELECT recipient
, recipient IS NULL AS all_null
, recipient IS NOT NULL AS all_notnull
, NOT recipient IS NULL AS some_notnull
, NOT recipient IS NOT NULL AS some_null
FROM (
VALUES
(('foo', 1 )::recipient)
, ((NULL , 2 )::recipient)
, ((NULL , NULL)::recipient)
) AS tbl(recipient);
Résultat:
recipient | all_null | all_notnull | some_notnull | some_null
-----------+----------+-------------+--------------+-----------
(foo,1) | f | t | t | f
(,2) | f | f | t | t
(,) | t | f | f | t
En relation: