Au cours de mes 7 années de carrière en tant que programmeur, j'ai interagi avec SQL via un ORM la plupart du temps. Une fonctionnalité de l'ORM Eloquent de Laravel que je trouve particulièrement utile est sa méthode updateOrInsert() :
DB::table('posts') ->updateOrInsert( ['slug' => 'about'], // matching condition ['content' => 'Like and subscribe'] // created or updated values );
Dans l'exemple ci-dessus, Eloquent recherchera une ligne dans le tableau des publications où le slug est égal à « à propos ». Si une ligne existe avec ce slug, Eloquent mettra à jour le contenu de cette ligne en « J'aime et abonnez-vous ». Si une ligne n'existe pas avec ce slug, Eloquent créera une nouvelle ligne avec le slug « à propos » et le contenu « Aimez et abonnez-vous ».
J'écris actuellement un script de migration pour déplacer les données de page d'un ancien site WordPress vers un nouveau site WordPress. Le script se connecte à la base de données de l'ancien site puis crée un fichier SQL pouvant être importé dans la base de données du nouveau site. Le nouveau site comporte déjà certaines pages qui ont été déplacées manuellement, mais leur contenu est peut-être obsolète. Lorsqu'une page existe déjà sur le nouveau site, nous ne souhaitons pas la créer à nouveau : nous souhaitons mettre à jour la page qui est déjà là. Nous pouvons déterminer si la page existe déjà en utilisant la colonne post_name dans la base de données WordPress, qui correspond au slug d'URL de la page.
Si le post_name était la clé primaire, nous pourrions accomplir quelque chose de similaire à la méthode createOrUpdate() d'Eloquent en utilisant une instruction REPLACE, mais le post_name n'est pas la clé primaire.
Si le post_name avait une contrainte unique, nous pourrions accomplir quelque chose de similaire à la méthode createOrUpdate() d'Eloquent en utilisant une instruction INSERT ... ON DUPLICATE KEY UPDATE, mais le post_name n'a pas de contrainte unique.
Ah, les joies de WordPress.
J'ai examiné l'instruction IF de MySQL, mais l'instruction IF ne fonctionne que dans les procédures stockées, les déclencheurs et les fonctions. Je ne voulais pas créer de procédures stockées dans le fichier SQL que j'importerais dans la base de données du nouveau site, j'ai donc dû rechercher d'autres options.
La solution la plus simple que j'ai pu trouver pour émuler la fonctionnalité updateOrInsert() d'Eloquent en SQL pur était de diviser le problème en deux :
Voici à quoi cela ressemble en pratique :
-- 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' );
REMARQUE : Cet exemple omet de nombreuses colonnes wp_posts requises par WordPress par souci de concision et de clarté.
Découvrir l'instruction INSERT ... SELECT a été le moment "aha" pour moi. Il est prévu d'utiliser les résultats d'une requête provenant d'une autre table pour effectuer plusieurs insertions à la fois. Cependant, vous pouvez utiliser et abuser des capacités de SQL en fournissant vos propres valeurs et en effectuant l'insertion uniquement lorsqu'une publication avec un nom de publication de "à propos" n'existe pas.
Est-ce la solution la plus élégante et la plus efficace à ce problème ? Probablement pas. Mais c'est suffisant pour une migration ponctuelle d'un site WordPress, et cela vous permet de mettre à jour ou d'insérer une ligne sans avoir besoin de procédures stockées ni de logique d'application. J'espère que cet article vous aidera à écrire des requêtes puissantes sans l'aide d'un ORM.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3