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

La prueba NO ES NULO para un registro no devuelve VERDADERO cuando se establece la variable

Veo dos posibles razones, por qué...

Ninguno de estos aumentos aparece en mi registro de mensajes

No registrado

En primer lugar, un NOTICE normalmente no se escribe en el registro de la base de datos con la configuración predeterminada. Cito el manual aquí:

log_min_messages (enum )

Controla qué niveles de mensajes se escriben en el registro del servidor. Los valores válidos son DEBUG5 , DEBUG4 , DEBUG3 , DEBUG2 , DEBUG1 , INFO , NOTICE , WARNING , ERROR , LOG , FATAL y PANIC . (...)
El valor predeterminado es ADVERTENCIA . Tenga en cuenta que LOG tiene un rango diferente aquí que en client_min_messages .

Énfasis en negrita mío. Tenga en cuenta también los valores predeterminados diferentes (NOTICE ) para client_min_messages (elemento anterior en el manual).

Prueba no válida

En segundo lugar, considere cómo se evalúa una expresión de fila. Una prueba row_variable IS NULL devuelve TRUE si (y solo si) cada uno de los elementos es NULL . Dado el siguiente ejemplo:

SELECT (1, NULL) IS NULL AS a     -- FALSE
      ,(1, NULL) IS NOT NULL AS b -- also FALSE

Ambos las expresiones devuelven FALSE . En otras palabras, una variable de fila (o registro) (1, NULL) tampoco es NULL , ni es NOT NULL . Por lo tanto, ambas pruebas fallan.

-> violín SQL con más detalles.

Más detalles, explicación, enlaces y una posible aplicación para este comportamiento en un CHECK restricción en esta respuesta relacionada:
NOT NULL restricción sobre un conjunto de columnas

Incluso puede asignar una variable de registro con NULL (rec := NULL ), lo que da como resultado que cada elemento sea NULL, si el tipo es un tipo de fila conocido. De lo contrario, estamos tratando con un registro anónimo y la estructura no está definida y, para empezar, no puede acceder a los elementos. Pero ese no es el caso con un rowtype como en tu ejemplo (que siempre es bien conocido).

Solución:FOUND

¿Cuál es la forma correcta de probar si recibió una fila de un SELECT * INTO? ?

Debe tener en cuenta que la fila podría ser NULL, incluso si estuviera asignada. La consulta podría muy bien haber devuelto un montón de valores NULL (si la definición de la tabla en su consulta permite valores NULL). Tal prueba no sería confiable por diseño.

Hay un enfoque simple y seguro. Utilice GET DIAGNOSTICS ... o (cuando corresponda) la variable especial FOUND :

SELECT * FROM my_table WHERE owner_id = 6 INTO my_var;

IF NOT FOUND THEN
   RAISE NOTICE 'Query did not return a row!';
END IF;

Detalles en el manual.