sql >> Databasteknik >  >> RDS >> PostgreSQL

Beteende av NOT LIKE med NULL-värden

Om NULL

'anything' NOT LIKE NULL ger NULL , inte TRUE .
Och bara TRUE kvalificerar sig för filteruttryck i en WHERE klausul.

De flesta funktioner returnerar NULLNULL input (det finns undantag). Det är karaktären hos NULL i alla korrekt RDBMS.

Om du önskar en singel uttryck, du kunde använd:

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

Det är dock knappast kortare eller snabbare. Detaljer i manualen.

Riktig fråga

Din fråga är fortfarande otillförlitlig. Enbart ett tabellnamn är inte unikt i en Postgres-databas, du måste ange schemanamnet utöver det eller förlita dig på den aktuella search_path för att hitta den första matchningen i den:

Relaterat:

  • Hur påverkar sökvägen identifierarens upplösning och det "aktuella schemat"
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%');

Bättre, men ändå inte skottsäker. En standardkolumn som börjar med 'nextval' gör inte en serial , än. Se:

  • Automatisk ökning av tabellkolumnen

För att vara säker, kontrollera om sekvensen som används "ägs" av kolumnen med pg_get_serial_sequence(table_name, column_name) .

Jag använder sällan informationsschemat själv. Dessa långsamma, uppsvällda vyer garanterar portabilitet över större versioner - och syftar till portabilitet till andra standardkompatibla RDBMS. Men för mycket är ändå oförenligt. Oracle implementerar inte ens informationsschemat (från 2015).

Dessutom saknas användbara Postgres-specifika kolumner i informationsschemat. I det här fallet kan jag fråga systemkatalogerna så här:

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

Snabbare och mer pålitlig, men mindre bärbar.

Manualen:

Katalogen pg_attrdef lagrar kolumns standardvärden. Huvudinformationen om kolumner lagras i pg_attribute (se nedan). Endast kolumner som uttryckligen anger ett standardvärde (när tabellen skapas eller kolumnen läggs till) kommer att ha en post här.

'table1'::regclass använder search_path för att lösa namnet, vilket undviker tvetydighet. Du kan schemakvalificera namnet för att åsidosätta:'myschema.table1'::regclass .

Relaterat:

  • Hitta det refererade tabellnamnet med hjälp av tabell-, fält- och schemanamn
  • Hämta standardvärdena för tabellkolumner i Postgres?


  1. Använda DMV ( Dynamic Management View ) och DMF ( Dynamic Management Function ) | SQL Server Performance Felsökning -4

  2. 2 sätt att lista alla funktioner i MySQL

  3. Vad är SQL Server Management Studio (SSMS)?

  4. Hur kan jag VÄLJA flera kolumner i ett CASE NÄR på SQL Server?