PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Comportamento de NOT LIKE com valores NULL

Sobre NULL


'anything' NOT LIKE NULL produz NULL , não TRUE .
E apenas TRUE qualifica para expressões de filtro em um WHERE cláusula.

A maioria das funções retorna NULL em NULL entrada (há exceções). Essa é a natureza de NULL em qualquer RDBMS adequado.

Se você deseja um single expressão, você poderia usar:
AND   (column_default LIKE 'nextval%')  IS NOT TRUE;

Isso dificilmente é mais curto ou mais rápido, no entanto. Detalhes no manual.

Consulta adequada


Sua consulta ainda não é confiável. Um nome de tabela sozinho não é exclusivo em um banco de dados Postgres, você precisa especificar o nome do esquema adicionalmente ou confiar no search_path atual para encontrar a primeira correspondência nele:

Relacionado:
  • Como o search_path influencia a resolução do identificador e o "esquema atual"
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%');

Melhor, mas ainda não à prova de balas. Uma coluna padrão começando com 'nextval' não faz um serial , ainda. Ver:
  • Coluna da tabela de incremento automático

Para ter certeza, verifique se a sequência em uso é "de propriedade" da coluna com pg_get_serial_sequence(table_name, column_name) .

Eu raramente uso o esquema de informações. Essas visualizações lentas e inchadas garantem a portabilidade entre as principais versões - e visam a portabilidade para outros RDBMS compatíveis com o padrão. Mas muito é incompatível de qualquer maneira. A Oracle nem implementa o esquema de informações (a partir de 2015).

Além disso, colunas úteis específicas do Postgres estão ausentes no esquema de informações. Para este caso, posso consultar os catálogos do sistema assim:
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) <> ''
   );

Mais rápido e confiável, mas menos portátil.

O manual:

O catálogo pg_attrdef armazena os valores padrão da coluna. As principais informações sobre as colunas são armazenadas em pg_attribute (ver abaixo). Apenas as colunas que especificam explicitamente um valor padrão (quando a tabela é criada ou a coluna é adicionada) terão uma entrada aqui.

'table1'::regclass usa o search_path para resolver o nome, o que evita ambiguidade. Você pode qualificar o nome pelo esquema para anular:'myschema.table1'::regclass .

Relacionado:
  • Encontre o nome da tabela referenciada usando o nome da tabela, do campo e do esquema
  • Obter os valores padrão das colunas da tabela no Postgres?