Injecter des données dans une autre table

Eléphanteau du PHP | 15 Messages

23 nov. 2008, 09:56

Bonjour,

Je suis perdu... Mes tentatives se soldent par des échecs, et je suis un peu découragé...

Voici l'exposé du problème...

Je possède deux tables.

La première, wp_postmeta, contient quatre champs :
meta_id,
post_id,
meta_key,
meta_value.

C'est la valeur "metakey"="description" qui m'intéresse.

En effet, je voudrai injecter ce contenu dans le champ post_excerpt dans la table wp-posts.

Cette table wp-posts contient un champ ID.

ID de la table wp-posts est l'équivalent du champ post_id de la table wp-postmeta (est-ce ça qu'on appelle une clé primaire ?).

J'arrive à conceptualiser le raisonnement, mais le traduire en commandes Sql me semble plus complexe : "insérer dans post_excerpt de la table wp-posts le contenu de la valeur metakey de la table, wp_postmeta lorsque metakey est égal à description"."

Est-ce correct ?

Mais où porter la mention de la clé primaire ?

Merci pour votre aide.

Cordialement, :D

Limpinpin

Eléphant du PHP | 254 Messages

23 nov. 2008, 16:54

Salut

post_id est une clé secondaire de ta table wp-postmeta qui correspond a la clé primaire de wp-posts, que tu as nommé ID
insérer dans post_excerpt de la table wp-posts le contenu de la valeur metakey de la table, wp_postmeta lorsque metakey est égal à description".
Cela veut il dire que la valeur de post_excerpt sera toujours egal a "description" ?

Eléphanteau du PHP | 15 Messages

23 nov. 2008, 18:08

Merci de la précision sur les clés, Furious ! :P

Oui, même si je me complique la vie parfois, post_excerpt sera toujours égal à description...

Bien cordialement,

Limpinpin

Eléphant du PHP | 254 Messages

24 nov. 2008, 00:09

Donc si je comprend bien tu veux savoir comment insérer une ligne dans ta table wp-posts pour chaque ligne dans wp_postmeta qui contient description ?

Eléphanteau du PHP | 15 Messages

24 nov. 2008, 11:50

Oui, Furious, c'est ça ! :roll:

Merci de ton aide.

Limpinpin

Eléphant du PHP | 254 Messages

24 nov. 2008, 17:34

Oki, j'prefere poser des questions avant hein :lol:

Bon alors en ce qui concerne un traitement en une fois ( c'est a dire ta premiere table est deja remplie et tu veux remplir la deuxieme ), personnellement je me casserais pas la tete et je ferais une procédure stockée ( depuis que j'y ai gouté je peux plus m'en passer ^^ mysql 5 ou plus il me semble )

Ensuite pour créer un enregistrement dans une table B, apres (ou avant) en avoir créé un dans une table A, tu as les triggers qui sont géré dans mysql aussi. Les triggers sont un peu comme des procédures stockées, mais ils se lancent automatiquement lors d'un update ou insert dans une table, avant ou apres celui ci.
Bon ceci dit les fois ou j'ai utilisé des triggers, c'etait pour palier a des défaut de conception, ou pendant des migration d'une conceptuel vers un autre, autant dire que ca ne m'est pas arrivé souvent, mais ca marche tres bien.

Si tu veux un exemple de procédure stockée je pourrais t'en filer un

Et pour finir je dirais juste que ton conceptuel me parait quelque peu étrange, pour le peu que j'en vois, et c'est peut etre pour ca que tes requetes ne sont pas forcément aussi simple qu'elles pourrait l'etre

:)

Eléphanteau du PHP | 15 Messages

25 nov. 2008, 09:03

Merci de ton attention.

Je vais essayer de me débrouiller avec tes premières indications. Si je n'y arrive pas, je reviendrai poser une question.

Bien à toi,

Limpinpin

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

25 nov. 2008, 10:23

Il existe une autre solution beaucoup plus simple : le INSERT ... SELECT.

Tu commences par faire ton SELECT qui sélectionne les données à injecter dans la seconde table, avec le WHERE qui rempli ta condition "chaque ligne de wp_postmeta qui contient description".
Tu vas donc obtenir une requete de ce genre :

Code : Tout sélectionner

SELECT champ1, champ2, champ3 FROM table1 WHERE mesConditions
à ce moment là, il te suffit d'ajouter le INSERT au début pour insérer dans une table les données que le SELECT aura retourné

Code : Tout sélectionner

INSERT INTO table2 (champ3, champ4, champ5) SELECT champ1, champ2, champ3 FROM table1 WHERE mesConditions
Attention, il faut que le SELECT remonte toutes les données nécessaire à l'INSERT. Mais si tu as une valeur fixe, ou un calcul, tu peux faire un truc de ce genre :

Code : Tout sélectionner

INSERT INTO table2 (champ3, champ4, champ5, champ6) SELECT champ1, "maChaine", 1, champ2+champ3 FROM table1 WHERE mesConditions
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 254 Messages

25 nov. 2008, 12:13

He oué c'est pas faux, l'insert multiple, dans ton cas c'est tout indiqué

mea culpa, j'ai avoué mon amour pour les procédurtes stockées un peu vite :)

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

25 nov. 2008, 12:55

Bonjour tout le monde.

Les 2 solutions se complètent, l'usage d'une procédure stockée est recommandé et la requête de zeus est son contenu.

Pour expliquer mieux la problématique posée au niveau conceptuel, il faut rappeler que c'est normal d'éprouver dans le cas posé un malaise conceptuel vu qu'en fait la procédure voulu par notre ami n'est qu'un transfert de données entre une source de données et une table spécifique. Et c'est la table de destination qui appartient au modèle de données métier et non celle qui fait office de source de données. Ce qui justifie la redondance de données soupçonnée dans un tel cas.

Ici, ce qu'il faut c'est un schéma de transfert de données et non un MCD conceptuel vu qu'on se positionne dans le modèle opérationnel de traitement.

Donc, comme l'a précisé zeus dans sa solution SQL (modèle opérationnel de traitement), il s'agit bien d'une importation de données dans la table de destination depuis une source de données:

Code : Tout sélectionner

INSERT INTO table_destination ([champs de destination]) SELECT [champs sources] FROM table_source
L'interface de données entre la procédure d'extraction (SELECT) et celle d'injection (INSERT) est constituée d'une connexion entre les [champs de destination] et les [champs sources]. Connexion qui doit respecter l'ordre, le type et la taille des données sujets du transfert.

Par exemple:

Code : Tout sélectionner

INSERT INTO table2 (A, B) SELECT C, D FROM table1;
Exige que les champs A, B et C, D soient respectivement égaux dans l'ordre de citation et dans leur type/taille
C'est à dire : A équivalent à C et B équivalent à D dans leur type/taille. sinon, si les types ne sont pas équivalents, il faut appliquer judicieusement des fonctions de conversion de type pour adapter la source à la destination. Si c'est un problème de taille, la source s'adapte forcément à la destination et l'on risque des troncatures ou des erreurs de données.

Pour stocker durablement cette opération ainsi conçue on peut utiliser une procédure stockée, ainsi, on enrichi notre modèle opérationnel de traitement enregistré dans le schéma de la base de données pour permettre aux développeurs de réutiliser les procédures pour construire des applications.

Exemple de déploiement de cette opération en procédure stockée:

Code : Tout sélectionner

delimiter | CREATE PROCEDURE transfert1 () BEGIN INSERT INTO table2 (A, B) SELECT C, D FROM table1; END
Pour l'exécuter cette procédure stockée on lance la commande:

Code : Tout sélectionner

CALL transfert1();
Tout ça c'est du SQL, et l'avantage de cette méthode d'intégration du modèle physique de données (tables, contraintes, indexes et relations durables) et du modèle opérationnel (triggers, vues, procédures stockées et fonctions) dans la même base de données, est d'abord la standardisation SQL, la réutilisabilité multi-plateforme de développement, la maintenance rapprochée et uni-langage...etc... sans rappeler le partage de charge de mise en œuvre et de fonctionnement des applications.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène