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".
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 mais simples que encontrei para emular a funcionalidade updateOrInsert() do Eloquent em SQL puro foi dividir o problema em duas partes:
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.
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