sql >> Base de Datos >  >> RDS >> PostgreSQL

Comportamiento de NOT LIKE con valores NULL

Acerca de NULL

'anything' NOT LIKE NULL produce NULL , no TRUE .
Y solo TRUE califica para expresiones de filtro en un WHERE cláusula.

La mayoría de las funciones devuelven NULL en NULL entrada (hay excepciones). Esa es la naturaleza de NULL en cualquier RDBMS adecuado.

Si desea un single expresión, usted podría usar:

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

Sin embargo, eso no es más corto o más rápido. Detalles en el manual.

Consulta adecuada

Su consulta aún no es confiable. Un nombre de tabla por sí solo no es único en una base de datos de Postgres, debe especificar el nombre del esquema además o confiar en el search_path actual para encontrar la primera coincidencia en él:

Relacionado:

  • ¿Cómo influye search_path en la resolución del identificador y el "esquema actual"?
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%');

Mejor, pero aún no a prueba de balas. Una columna predeterminada que comienza con 'nextval' no hace un serial , aún. Ver:

  • Columna de tabla de incremento automático

Para estar seguro, verifique si la secuencia en uso es "propiedad" de la columna con pg_get_serial_sequence(table_name, column_name) .

Raramente uso el esquema de información yo mismo. Esas vistas lentas e infladas garantizan la portabilidad entre las principales versiones y apuntan a la portabilidad a otros RDBMS que cumplen con los estándares. Pero demasiado es incompatible de todos modos. Oracle ni siquiera implementa el esquema de información (a partir de 2015).

Además, faltan columnas útiles específicas de Postgres en el esquema de información. Para este caso, podría consultar los catálogos del sistema de esta manera:

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

Más rápido y más confiable, pero menos portátil.

El manual:

El catálogo pg_attrdef almacena los valores predeterminados de las columnas. La información principal sobre las columnas se almacena en pg_attribute (vea abajo). Solo las columnas que especifican explícitamente un valor predeterminado (cuando se crea la tabla o se agrega la columna) tendrán una entrada aquí.

'table1'::regclass utiliza la search_path para resolver el nombre, lo que evita la ambigüedad. Puede calificar el esquema del nombre para anular:'myschema.table1'::regclass .

Relacionado:

  • Encuentre el nombre de la tabla a la que se hace referencia usando el nombre de tabla, campo y esquema
  • ¿Obtener los valores predeterminados de las columnas de la tabla en Postgres?