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 / 228046
Accepted
ChrisJ
ChrisJ
Asked: 2019-01-25 19:39:38 +0800 CST2019-01-25 19:39:38 +0800 CST 2019-01-25 19:39:38 +0800 CST

Por que preciso converter NULL para o tipo de coluna?

  • 772

Eu tenho um auxiliar que está gerando algum código para fazer atualizações em massa para mim e gera SQL que se parece com isso:

(Ambos os campos ativo e principal são do tipo boolean)

UPDATE fields as t set "active" = new_values."active","core" = new_values."core"
FROM (values 
(true,NULL,3419),
(false,NULL,3420)
) as new_values("active","core","id") WHERE new_values.id = t.id;

No entanto, ele falha com:

ERROR: column "core" is of type boolean but expression is of type text

Eu posso fazê-lo funcionar adicionando ::booleanaos nulos, mas isso parece estranho, por que NULL é considerado do tipo TEXT?

Além disso, é um pouco complicado de converter porque exigiria um pouco de retrabalho do código para saber para que tipo deve converter NULLs (a lista de colunas e valores está sendo gerada automaticamente a partir de uma matriz simples de objetos JSON) .

Por que isso é necessário e existe uma solução mais elegante que não exija que o código gerador saiba o tipo de NULLs?

Se for relevante, estou usando sequelize sobre Node.JS para fazer isso, mas também estou obtendo o mesmo resultado no cliente de linha de comando Postgres.

postgresql null
  • 1 1 respostas
  • 10652 Views

1 respostas

  • Voted
  1. Best Answer
    dezso
    2019-01-25T23:43:29+08:002019-01-25T23:43:29+08:00

    Esta é uma descoberta interessante. Normalmente, um NULL não tem tipo de dados assumido, como você pode ver aqui:

    SELECT pg_typeof(NULL);
    
     pg_typeof 
    ───────────
     unknown
    

    Isso muda quando uma VALUEStabela entra na imagem:

    SELECT pg_typeof(core) FROM (
        VALUES (NULL)
    ) new_values (core);
    
     pg_typeof 
    ───────────
     text
    

    Esse comportamento é descrito no código-fonte em https://doxygen.postgresql.org/parse__coerce_8c.html#l01373 :

     /*
      * If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
      * then resolve as type TEXT.  This situation comes up with constructs
      * like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
      * UNION SELECT 'bar'; It might seem desirable to leave the construct's
      * output type as UNKNOWN, but that really doesn't work, because we'd
      * probably end up needing a runtime coercion from UNKNOWN to something
      * else, and we usually won't have it.  We need to coerce the unknown
      * literals while they are still literals, so a decision has to be made
      * now.
      */
    

    (Sim, o código-fonte do PostgreSQL é relativamente fácil de entender e na maioria dos lugares, graças a excelentes comentários.)

    A saída, no entanto, pode ser a seguinte. Digamos que você esteja sempre gerando VALUESque correspondam a todas as colunas de uma determinada tabela (veja a segunda nota abaixo para outros casos). Do seu exemplo, um pequeno truque poderia ajudar:

    SELECT (x).* FROM (VALUES ((TRUE, NULL, 1234)::fields)) t(x);
    
     active │ core │  id  
    ────────┼──────┼──────
     t      │      │ 1234
    

    Aqui você usa expressões de linha convertidas para o tipo da tabela e, em seguida, extrai-as de volta para uma tabela.

    Com base no acima, seu UPDATEpoderia parecer

    UPDATE fields AS t set active = (x).active, core = (x).core
    FROM ( VALUES
               ((true, NULL, 3419)::fields),
               ((false, NULL, 3420)::fields)
         ) AS new_values(x) WHERE (x).id = t.id;
    

    Notas:

    • Eu removi as aspas duplas para melhor legibilidade humana, mas você pode mantê-las, pois elas ajudam na geração de nomes (coluna).
    • se você precisar apenas de um subconjunto das colunas, poderá criar tipos personalizados para essa finalidade. Use-os da mesma forma que você faria acima (onde eu uso o tipo criado automaticamente com a tabela, mantendo a estrutura de linhas desta última).

    Olhe para a coisa toda trabalhando em dbfiddle .

    • 19

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