PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comportement de NOT LIKE avec des valeurs NULL

À propos de NULL

'anything' NOT LIKE NULL donne NULL , pas TRUE .
Et uniquement TRUE se qualifie pour les expressions de filtre dans un WHERE clause.

La plupart des fonctions renvoient NULL sur NULL entrée (il y a des exceptions). C'est la nature de NULL dans tout SGBDR approprié.

Si vous désirez un célibataire expression, vous pourriez utiliser :

AND   (column_default LIKE 'nextval%')  IS NOT TRUE;

C'est à peine plus court ou plus rapide, cependant. Détails dans le manuel.

Requête appropriée

Votre requête n'est toujours pas fiable. Un nom de table seul n'est pas unique dans une base de données Postgres, vous devez spécifier le nom du schéma en plus ou vous fier au search_path actuel pour trouver la première correspondance :

Connexe :

  • Comment le search_path influence-t-il la résolution de l'identifiant et le "schéma actuel"
SELECT column_name
FROM   information_schema.columns
WHERE  table_name = 'hstore1'
AND    table_schema = 'public'   -- your schema
AND   (column_default IS NULL OR
       column_default NOT LIKE 'nextval%');

Mieux, mais toujours pas à l'épreuve des balles. Une colonne par défaut commençant par 'nextval' ne crée pas de serial , encore. Voir :

  • Colonne de tableau d'incrémentation automatique

Pour être sûr, vérifiez si la séquence utilisée est "possédée" par la colonne avec pg_get_serial_sequence(table_name, column_name) .

J'utilise rarement le schéma d'information moi-même. Ces vues lentes et gonflées garantissent la portabilité entre les principales versions - et visent la portabilité vers d'autres RDBMS conformes aux normes. Mais trop est incompatible de toute façon. Oracle n'implémente même pas le schéma d'information (à partir de 2015).

En outre, des colonnes utiles spécifiques à Postgres manquent dans le schéma d'informations. Dans ce cas, je pourrais interroger les catalogues système comme ceci :

SELECT *
FROM   pg_catalog.pg_attribute a
WHERE  attrelid = 'table1'::regclass
AND    NOT attisdropped   -- no dropped (dead) columns
AND    attnum > 0         -- no system columns
AND   NOT EXISTS (
   SELECT FROM pg_catalog.pg_attrdef d
   WHERE  (d.adrelid, d.adnum) = (a.attrelid, a.attnum)
   AND    d.adsrc LIKE 'nextval%'
   AND    pg_get_serial_sequence(a.attrelid::regclass::text, a.attname) <> ''
   );

Plus rapide et plus fiable, mais moins portable.

Le manuel :

Le catalogue pg_attrdef stocke les valeurs par défaut des colonnes. Les principales informations sur les colonnes sont stockées dans pg_attribute (voir ci-dessous). Seules les colonnes qui spécifient explicitement une valeur par défaut (lorsque la table est créée ou que la colonne est ajoutée) auront une entrée ici.

'table1'::regclass utilise le search_path pour résoudre le nom, ce qui évite l'ambiguïté. Vous pouvez qualifier le nom de schéma pour remplacer :'myschema.table1'::regclass .

Connexe :

  • Recherchez le nom de la table référencée à l'aide du nom de la table, du champ et du schéma
  • Obtenir les valeurs par défaut des colonnes de table dans Postgres ?