AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 157691
Accepted
Anil
Anil
Asked: 2016-12-10 07:25:16 +0800 CST2016-12-10 07:25:16 +0800 CST 2016-12-10 07:25:16 +0800 CST

(x NÃO É NULO) vs (NÃO x É NULO) no PostgreSQL

  • 772

Por que x IS NOT NULLnão é igual a NOT x IS NULL?

Este código:

CREATE TABLE bug_test (
    id int,
    name text
);

INSERT INTO bug_test
VALUES (1, NULL);

DO $$
DECLARE
    v_bug_test bug_test;
BEGIN
    RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NULL);
    RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NOT NULL);
    RAISE NOTICE '%: %', v_bug_test, (NOT v_bug_test IS NULL);

    SELECT *
    INTO v_bug_test
    FROM bug_test
    WHERE id = 1;

    RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NULL);
    RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NOT NULL);
    RAISE NOTICE '%: %', v_bug_test, (NOT v_bug_test IS NULL);
END
$$;

DROP TABLE bug_test;

dá a seguinte saída:

(,): t
(,): f
(,): f
(1,): f
(1,): f ???
(1,): t

enquanto eu esperaria obter esta saída:

(,): t
(,): f
(,): f
(1,): f
(1,): t <<<
(1,): t
postgresql null
  • 1 1 respostas
  • 3627 Views

1 respostas

  • Voted
  1. Best Answer
    joanolo
    2016-12-10T08:14:56+08:002016-12-10T08:14:56+08:00

    Você tem que distinguir duas situações: você compara uma COLUMN com NULL, ou você compara toda a ROW (RECORD) com NULL.

    Considere a seguinte consulta:

    SELECT
        id, 
        txt, 
        txt     IS NULL AS txt_is_null, 
        NOT txt IS NULL AS not_txt_is_null, 
        txt IS NOT NULL AS txt_is_not_null
    FROM
        (VALUES
            (1::integer, NULL::text)
        ) 
        AS x(id, txt) ;
    

    Você consegue isso:

    +----+-----+-------------+-----------------+-----------------+
    | id | txt | txt_is_null | not_txt_is_null | txt_is_not_null | 
    +----+-----+-------------+-----------------+-----------------+
    |  1 |     | t           | f               | f               | 
    +----+-----+-------------+-----------------+-----------------+
    

    Isso é, eu acho, o que você e eu esperaríamos. Você está verificando uma COLUNA contra NULL e obtém "txt IS NOT NULL" e "NOT txt IS NULL" são equivalentes.

    No entanto, se você fizer uma verificação diferente:

    SELECT
        id, 
        txt, 
        x       IS NULL AS x_is_null,
        NOT x   IS NULL AS not_x_is_null,
        x   IS NOT NULL AS x_is_not_null
    FROM
        (VALUES
            (1, NULL)
        ) 
        AS x(id, txt) ;
    

    Então você consegue

    +----+-----+-----------+---------------+---------------+
    | id | txt | x_is_null | not_x_is_null | x_is_not_null |
    +----+-----+-----------+---------------+---------------+
    |  1 |     | f         | t             | f             |
    +----+-----+-----------+---------------+---------------+
    

    Isso pode ser surpreendente. Uma coisa parece razoável (x IS NULL) e (NOT x IS NULL) são o oposto um do outro. A outra coisa (o fato de que nem "x IS NULL" nem "x IS NOT NULL" são verdadeiros) parece estranho.

    No entanto, é isso que a documentação do PostgreSQL diz que deve acontecer:

    Se a expressão tiver valor de linha, IS NULL será verdadeiro quando a própria expressão de linha for nula ou quando todos os campos da linha forem nulos, enquanto IS NOT NULL será verdadeiro quando a própria expressão de linha for não nula e todos os campos da linha forem não nulo. Devido a esse comportamento, IS NULL e IS NOT NULL nem sempre retornam resultados inversos para expressões com valor de linha; em particular, uma expressão com valor de linha que contém campos nulos e não nulos retornará false para ambos os testes. Em alguns casos, pode ser preferível escrever a linha IS DISTINCT FROM NULL ou a linha IS NOT DISTINCT FROM NULL, que simplesmente verificará se o valor geral da linha é nulo sem nenhum teste adicional nos campos da linha.

    Devo confessar que acho que nunca usei uma comparação de valor de linha contra nulo, mas acho que, se houver essa possibilidade, pode haver algum caso de uso para isso. Eu não acho que é comum, de qualquer maneira.

    • 18

relate perguntas

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • NULL ou NOT NULL por padrão?

  • Quando usar NULL e quando usar uma string vazia?

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve