web-dev-qa-db-fra.com

Postgres HSTORE Vérifiez si une clé existe et ne correspond pas à la valeur

J'ai un champ HSTORE dans une table d'audit qui stocke tous les champs qui ont changé à la suite d'une opération.

Sur les insertions, la clé, updated_by dans changed_fields est null et sur les mises à jour du système, il est défini sur system. Je souhaite retourner toutes les lignes où la clé n'est pas définie ou la clé n'est pas system mais je suis perdu sur la façon de faire cela.

Jusqu'à présent j'ai essayé

select changed_fields -> 'updated_by' 
from audit.logged_actions 
where (changed_fields -> 'updated_by' != 'system' 
       or defined(changed_fields, 'updated_by') = false) 
order by event_id desc

Mais cela ne fonctionne pas et je ne suis pas tout à fait sûr pourquoi. Des idées sur ce que je fais mal?

5
Gaurav

L'utilisation de defined() dans la documentation:

hSTORE contient-il une valeur non nulle pour la clé?

En plus d'une valeur nulle pour une clé existante, il renvoie FALSE aussi lorsque la clé n'existe pas.

Pour le garder propre, vous voudrez peut-être utiliser la fonction exist() à la place:

SELECT exist('"bla" => 1234', 'bloo');
 exist 
───────
 f

Donc, votre requête ressemblerait à

SELECT changed_fields -> 'updated_by' 
  FROM audit.logged_actions 
 WHERE changed_fields -> 'updated_by' <> 'system' 
       OR NOT exist(changed_fields, 'updated_by')
 ORDER by event_id desc;

Notes:

  • ne testez jamais les valeurs logiques à l'aide de l'opérateur d'égalité (sauf si vous ne pouvez être vraiment Sûr La valeur ne peut pas être null). Vous pouvez utiliser directement la valeur si elle est garantie de ne pas être nulle (comme dans ma requête) ou d'utiliser l'opérateur IS .
  • Dans la forme actuelle, la requête vérifie un simple "ou" - de votre libellé, il n'est pas tout à fait clair ce qui devrait arriver lorsque les deux conditions sont vraies.
10
dezso