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 / 129522
Accepted
Oliver Salzburg
Oliver Salzburg
Asked: 2016-02-17 07:59:22 +0800 CST2016-02-17 07:59:22 +0800 CST 2016-02-17 07:59:22 +0800 CST

Como obter o ID da linha conflitante no upsert?

  • 772

Tenho uma tabela tagcom 2 colunas: id(uuid) e name(texto). Agora quero inserir uma nova tag na tabela, mas se a tag já existir, quero simplesmente obter o idregistro existente.

Presumi que poderia usar apenas ON CONFLICT DO NOTHINGem combinação com RETURNING "id":

INSERT INTO
    "tag" ("name")
VALUES( 'foo' )
ON CONFLICT DO NOTHING
RETURNING "id";

Mas isso retorna um conjunto de resultados vazio, se a tag com o nome "foo" já existir.

Em seguida, alterei a consulta para usar uma DO UPDATEcláusula noop:

INSERT INTO
    "tag" ("name")
VALUES( 'foo' )
ON CONFLICT ("name") DO UPDATE SET "name" = 'foo'
RETURNING "id";

Isso funciona como pretendido, mas é um pouco confuso, porque estou apenas definindo o nome para o valor já existente.

Esta é a maneira de resolver esse problema ou há uma abordagem mais simples que estou perdendo?

postgresql upsert
  • 2 2 respostas
  • 17976 Views

2 respostas

  • Voted
  1. Best Answer
    ypercubeᵀᴹ
    2016-02-18T11:08:38+08:002016-02-18T11:08:38+08:00

    Isso funcionará (pelo que testei) em todos os 3 casos, se os valores a serem inseridos forem todos novos ou já estiverem na tabela ou uma mistura:

    WITH
      val (name) AS
        ( VALUES                          -- rows to be inserted
            ('foo'),
            ('bar'),
            ('zzz')
        ),
      ins AS
        ( INSERT INTO
            tag (name)
          SELECT name FROM val
          ON CONFLICT (name) DO NOTHING
          RETURNING id, name              -- only the inserted ones
        )
    SELECT COALESCE(ins.id, tag.id) AS id, 
           val.name
    FROM val
      LEFT JOIN ins ON ins.name = val.name
      LEFT JOIN tag ON tag.name = val.name ;
    

    Provavelmente existem outras maneiras de fazer isso, talvez sem usar a nova ON CONFLICTsintaxe.

    • 14
  2. Andriy M
    2016-02-19T02:56:36+08:002016-02-19T02:56:36+08:00

    Não faço ideia de como isso funcionará, mas apenas como outra opção para tentar, aqui está fazendo o mesmo da maneira antiga (sem ON CONFLICT):

    WITH items (name) AS (VALUES ('foo'), ('bar'), ('zzz')),
         added        AS
          (
            INSERT INTO tag (name)
    
            SELECT name FROM items
            EXCEPT
            SELECT name FROM tag
    
            RETURNING id
          )
    SELECT id FROM added
    
    UNION ALL
    
    SELECT id FROM tag
    WHERE name IN (SELECT name FROM items)
    ;
    

    Ou seja, insira apenas os nomes [únicos] não encontrados na tagtabela e retorne os IDs; combine isso com os IDs dos nomes que existem em tag, para a saída final. Você também pode jogar namena saída, conforme sugerido por ypercubeᵀᴹ , para saber qual ID corresponde a qual nome.

    • 4

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

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

  • Sequências Biológicas do UniProt no PostgreSQL

  • 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