"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Upsert uma linha em um banco de dados que não usa chaves primárias ou restrições exclusivas

Upsert uma linha em um banco de dados que não usa chaves primárias ou restrições exclusivas

Publicado em 2024-11-08
Navegar:239

Upsert a row in a DB that doesn

Durante minha carreira de 7 anos como programador, interagi com SQL por meio de um ORM na maior parte do tempo. Um recurso do Eloquent ORM do Laravel que considero particularmente útil é o método updateOrInsert():

DB::table('posts')
    ->updateOrInsert(
        ['slug' => 'about'], // matching condition
        ['content' => 'Like and subscribe'] // created or updated values
    );

No exemplo acima, o Eloquent irá procurar por uma linha na tabela de posts onde o slug é igual a "about". Se existir uma linha com esse slug, o Eloquent atualizará o conteúdo dessa linha para "Curtir e assinar". Se uma linha não existir com esse slug, o Eloquent criará uma nova linha com o slug "about" e o conteúdo de "Curtir e se inscrever".

O problema: nenhuma chave primária ou restrições exclusivas

Atualmente estou escrevendo um script de migração para mover dados de páginas de um site WordPress antigo para um novo site WordPress. O script se conecta ao banco de dados do site antigo e cria um arquivo SQL que pode ser importado para o banco de dados do novo site. O novo site já possui algumas páginas que foram movidas manualmente, mas seu conteúdo pode estar desatualizado. Quando já existe uma página no novo site, não queremos criá-la novamente: queremos atualizar a página que já está lá. Podemos determinar se a página já existe usando a coluna post_name no banco de dados do WordPress, que corresponde ao slug de URL da página.

Se o post_name fosse a chave primária, poderíamos realizar algo semelhante ao método createOrUpdate() do Eloquent usando uma instrução REPLACE, mas o post_name não é a chave primária.

Se o post_name tivesse uma restrição exclusiva, poderíamos realizar algo semelhante ao método createOrUpdate() do Eloquent usando uma instrução INSERT ... ON DUPLICATE KEY UPDATE, mas o post_name não possui uma restrição exclusiva.

Ah, as alegrias do WordPress.

Examinei a instrução IF do MySQL, mas a instrução IF só funciona em procedimentos armazenados, gatilhos e funções. Eu não queria criar procedimentos armazenados no arquivo SQL que iria importar para o banco de dados do novo site, então tive que procurar outras opções.

A solução: 2 afirmações

A solução mais simples que encontrei para emular a funcionalidade updateOrInsert() do Eloquent em SQL puro foi dividir o problema em duas partes:

  1. Atualize todas as linhas existentes com um slug correspondente.
  2. Crie uma nova linha se não houver linhas com slugs correspondentes.

Isso é na prática:

-- Update the post if it already exists.

UPDATE wp_posts
SET post_type = 'page',
    post_title = 'About',
    post_content = 'Like and subscribe'
WHERE post_name = 'about';

-- Create a new post if it does not exist.

INSERT INTO wp_posts (post_name, post_type, post_title, post_content)
SELECT 'about', 'page', 'About', 'Like and subscribe'
WHERE NOT EXISTS (
    SELECT 1
    FROM wp_posts
    WHERE post_name = 'about'
);

NOTA: Este exemplo omite muitas das colunas wp_posts obrigatórias do WordPress para maior brevidade e clareza.

Aprender sobre a instrução INSERT ... SELECT foi um momento "aha" para mim. Pretende-se usar os resultados de uma consulta de outra tabela para realizar muitas inserções de uma só vez. No entanto, você pode usar e abusar dos recursos do SQL, fornecendo seus próprios valores e executando a inserção somente quando uma postagem com post_name de "about" não existir.

Esta é a solução mais elegante e eficiente para este problema? Provavelmente não. Mas é bom o suficiente para uma migração única de um site WordPress e permite atualizar ou inserir uma linha sem precisar de procedimentos armazenados ou qualquer lógica de aplicativo. Esperamos que esta postagem ajude você a escrever consultas poderosas sem a ajuda de um ORM.

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/tylerlwsmith/upsert-a-row-in-a-db-that-doesnt-use-primary-keys-or-unique-constraints-2jnl?1Se houver algum violação, entre em contato com [email protected] para excluir
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3