Maison >base de données >tutoriel mysql >Insérer une ligne dans une base de données qui n'utilise pas de clés primaires ni de contraintes uniques

Insérer une ligne dans une base de données qui n'utilise pas de clés primaires ni de contraintes uniques

Linda Hamilton
Linda Hamiltonoriginal
2024-10-19 10:52:29359parcourir

Upsert a row in a DB that doesn

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 de "J'aime et abonnez-vous".

Le problème : pas de clé primaire ni de contraintes uniques

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 : 2 affirmations

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 :

  1. Mettez à jour toutes les lignes existantes avec un slug correspondant.
  2. Créez une nouvelle ligne s'il n'y a aucune ligne avec des slugs correspondants.

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é.

Apprendre 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 lorsque vous écrivez des requêtes puissantes sans l'aide d'un ORM.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn