PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Verhalten von NOT LIKE mit NULL-Werten

Über NULL

'anything' NOT LIKE NULL ergibt NULL , nicht TRUE .
Und nur TRUE qualifiziert für Filterausdrücke in einem WHERE Klausel.

Die meisten Funktionen geben NULL zurück auf NULL Eingang (es gibt Ausnahmen). Das ist die Natur von NULL in beliebigen richtiges RDBMS.

Wenn Sie ein Einzelzimmer wünschen Ausdruck, Sie könnten verwenden:

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

Das ist aber kaum kürzer oder schneller. Details im Handbuch.

Richtige Abfrage

Ihre Abfrage ist immer noch unzuverlässig. Ein Tabellenname allein ist in einer Postgres-Datenbank nicht eindeutig, Sie müssen den Schemanamen zusätzlich angeben oder sich auf den aktuellen search_path verlassen um die erste Übereinstimmung darin zu finden:

Verwandte:

  • Wie beeinflusst der Suchpfad die Identifikatorauflösung und das "aktuelle Schema"
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%');

Besser, aber immer noch nicht kugelsicher. Ein Spaltenstandard, der mit „nextval“ beginnt, macht keinen serial , noch. Siehe:

  • Tabellenspalte automatisch erhöhen

Prüfen Sie zur Sicherheit mit pg_get_serial_sequence(table_name, column_name), ob die verwendete Sequenz der Spalte "gehört". .

Ich selbst benutze das Informationsschema selten. Diese langsamen, aufgeblähten Ansichten garantieren die Übertragbarkeit über Hauptversionen hinweg – und zielen auf die Übertragbarkeit auf andere standardkonforme RDBMS ab. Aber zu viel ist sowieso unverträglich. Oracle implementiert nicht einmal das Informationsschema (Stand 2015).

Außerdem fehlen nützliche Postgres-spezifische Spalten im Informationsschema. Für diesen Fall könnte ich die Systemkataloge wie folgt abfragen:

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) <> ''
   );

Schneller und zuverlässiger, aber weniger portabel.

Das Handbuch:

Der Katalog pg_attrdef speichert Standardwerte für Spalten. Die Hauptinformationen über Spalten werden in pg_attribute gespeichert (siehe unten). Nur Spalten, die ausdrücklich einen Standardwert angeben (wenn die Tabelle erstellt oder die Spalte hinzugefügt wird), haben hier einen Eintrag.

'table1'::regclass verwendet den search_path um den Namen aufzulösen, was Mehrdeutigkeiten vermeidet. Sie können den Namen schemaqualifizieren, um ihn zu überschreiben:'myschema.table1'::regclass .

Verwandte:

  • Suchen Sie den referenzierten Tabellennamen anhand des Tabellen-, Feld- und Schemanamens
  • Standardwerte von Tabellenspalten in Postgres erhalten?