Insertion dans tables de correspondances

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Insertion dans tables de correspondances

Re: Insertion dans tables de correspondances

par BaLiSTiK » 08 juin 2010, 10:46

Je suis allez voir comment c'était fait sur CakePHP (car c'est le framework utilisé au travail) :
Pour MySQL : SELECT LAST_INSERT_ID() AS insertID
PostgreSQL : SELECT last_value AS max FROM \"{$seq}\" avec $seq de la forme table_champ_seq

Je pense avoir trouvé ma solution, je vais mettre ça en place dans la journée ^^.

Re: Insertion dans tables de correspondances

par stealth35 » 07 juin 2010, 18:02

Justement non, je construit toutes mes requêtes SQL comme ça, le substr sur la requête SQL n est pas concaténée, sinon toute la requête SQL est tronquée.
tu fais ca
$sqlTag = 'INSERT INTO tags(nom_tag) VALUES(';
$sqlTag .= '\''.$value.'\',';
$sqlTag = substr($sqlTag, 0,strlen($sqlTag)-1);
$sqlTag .= ');'; 
$text = 'blabla';
$text .= 'truc';
$text = 'nouveau';
$text .= 'hello';
	
echo $text;
//nouveauhello

sinon pour le coup des virgule, tu peu mettre les élément dans un tableau et faire un implode apres
	$arr = array('blabla', 'truc', 'nouveau', 'hello');
	echo implode(',', $arr);
//blabla,truc,nouveau,hello

Re: Insertion dans tables de correspondances

par BaLiSTiK » 07 juin 2010, 17:55

ta pas oublie un point ici
$sqlTag = substr($sqlTag, 0,strlen($sqlTag)-1); 
et pourquoi tu fais substr($sqlTag, 0,strlen($sqlTag)-1) ?
Justement non, je construit toutes mes requêtes SQL comme ça, le substr sur la requête SQL n est pas concaténée, sinon toute la requête SQL est tronquée.
Dans mes foreach(), j'applique la valeur à insérer comme ceci : $sql.= '\''.$value.'\',';, et donc quand le dernier tour de boucle est fait, il reste une virgule en trop, d'ou le substr().
Mais effectivement dans le cas de la requête SQL du tag, il n est pas nécéssaire car c est toute la requête qui est dans la boucle ^^.
sinon au lieu d'utilise les fonctions php tu peux en effet creer la requête direct (sous mysql c'est SELECT LAST_INSERT_ID();)
:wink:
Je vais surement utiliser cette solution au finale, mais c est plus la fonction équivalente de Postgres qui m'interesse.

Re: Insertion dans tables de correspondances

par stealth35 » 07 juin 2010, 17:46

ta pas oublie un point ici
$sqlTag = substr($sqlTag, 0,strlen($sqlTag)-1); 
et pourquoi tu fais substr($sqlTag, 0,strlen($sqlTag)-1) ?


sinon au lieu d'utilise les fonctions php tu peux en effet creer la requête direct (sous mysql c'est SELECT LAST_INSERT_ID();)
:wink:

Re: Insertion dans tables de correspondances

par BaLiSTiK » 07 juin 2010, 17:44

je viens de coder cette fonction (que j ai mis dans une class de connexion BD, cf mon topic sur le forum PHP Objet ^^):
	function recupLastId($sRequete){
		try{
			switch($this->psConnect){
				case 1 :
					$lastId = mysql_insert_id();
					break;
				case 2 :
					$lastId = pg_last_oid($sRequete);
					break;	
			}
			return $lastId;
		}catch(MyException $e){
			echo $e->getError();
		}//fin try/catch
	}
Je teste avec Postgresql car je n ai pas de BD Mysql au boulot.

Dans ma class Article, dans la méthode d'ajout d'articles, voila comment j ai fais :
//Recuperation du dernier ID : 
			$lastIdArticle = $this->m_nAccesBD->recupLastId($this->req);
			/**
			 * Ajout des tags
			 */
			//Explosion de la chaine de caracteres pour recuperer les tags séparer par des ;
			$tags = explode(";",$this->tags);
			$dataTags = json_encode($tags); //Conversion format JSON
			//Preparation des données a l insertion
			$this->donneesTags =  $this->m_nAccesBD->prepareInsertionDonnees($dataTags);	
			
			//Requete SQL tags
			//Pour chaque mot, on fait une insertion sql
			foreach($this->donneesTags as $key => $value){
				
				$sqlTag = 'INSERT INTO tags(nom_tag) VALUES(';
				$sqlTag .= '\''.$value.'\',';
				$sqlTag = substr($sqlTag, 0,strlen($sqlTag)-1); 
				$sqlTag .= ');'; 
				
				//Insertion de la requete SQL
				$this->reqTag = $this->m_nAccesBD->requete($sqlTag);	
				//Recuperation de l ID de la requete SQL
				$lastIdTag = $this->m_nAccesBD->recupLastId($this->reqTag);
				
				//Insertion dans la table de lien
				$sqlLienArtTag = 'INSERT INTO articles_tags VALUES ('.$lastIdArticle.', '.$lastIdTag.')';
				$this->reqLien = $this->m_nAccesBD->requete($sqlLienArtTag);
			}	
Mais le problème est que mon lastInsertId ne retourne rien. Dans la fonction pg_last_oid(), j'envoie bien en paramètres, le résultat retourné par pg_query et non la requête SQL. Sur la doc de PHP, il y a cette note :
Pour obtenir la valeur d'un champ SERIAL dans une ligne insérée, il est nécessaire d'utiliser la fonction CURRVAL de PostgreSQL en nommant la séquence à qui la dernière valeur est requise. Si le nom de la séquence est inconnu, la fonction PostgreSQL 8.0 pg_get_serial_sequence est nécessaire.

PostgreSQL 8.1 a une fonction LASTVAL qui retourne la valeur de la séquence la plus récemment utilisée de la session. Ceci permet d'éviter de nommer la séquence, la table ou la colonne.
Donc cette fonction n'a pas l'air d'être recommandé finalement !!

Re: Insertion dans tables de correspondances

par stealth35 » 07 juin 2010, 17:29

Merci de ta réponse, mais la fonction "last_insert_id()" correspond-elle aux fonction mysql_insert_id() pour MySQL et pg_last_oid() pour PostgreSQL et serait une fonction que je dois développer ?
ouai ca correspond a ca :wink:

Re: Insertion dans tables de correspondances

par BaLiSTiK » 07 juin 2010, 16:26

Merci de ta réponse, mais la fonction "last_insert_id()" correspond-elle aux fonction mysql_insert_id() pour MySQL et pg_last_oid() pour PostgreSQL et serait une fonction que je dois développer ?

Re: Insertion dans tables de correspondances

par stealth35 » 07 juin 2010, 16:05

y'a surement moyen avec des TRIGGER, sinon version schéma on pourrait faire
INSERT INTO article //blablabla
$id_article = last_insert_id();

foreach($tags as $tag)
{
    INSERT IGNORE INTO tags //blabla;
    if(affect_row)
    {
        $id_tag = last_insert_id;
    }
    else
    {
        $id_tag = SELECT id FROM tag WHERE tag = $tag
    }

    INSERT INTO articles_tags VALUES ($id_article, $id_tag)
}

Insertion dans tables de correspondances

par BaLiSTiK » 07 juin 2010, 15:21

Bonjour,

Je suis en train de créér un "cloud tag" pour mon projet web (toujours le même ^^...) et j'ai un soucis au niveau de l'insertion des tags en SQL.
J ai 3 tables en jeu :
- La table Articles, contenant mes articles
- Ma table Tags, contenant tous les tags
- Une table articles_tags, qui lie articles à tag
C est donc une relation N..N entre Articles et tags.

Voila la structure des tables :
/*==============================================================*/
/* Table : TAGS                                             */
/*==============================================================*/
create table tags(
	id_tag serial NOT NULL,
	nom_tag varchar(70),
	primary key (id_tag)
);
/*==============================================================*/
/* Table : articles_tags : table de lien entre article 
 * et tags : relationn n..n                                  */
/*==============================================================*/
create table articles_tags(
	id_article_ref integer,
	id_tag_ref integer
);

/*==============================================================*/
/* Table : ARTICLES                                             */
/*==============================================================*/
create table articles
(
   id_article                     serial NOT NULL,
   id_theme                       integer,
   id_user                        integer,
   titre_article                  text,
   titre_url_article              varchar(50),
   article                        text,
   date_article                   numeric,
   primary key (id_article)
);

/** Clés etrangeres pour la gestion des tags **/      
alter table articles_tags add constraint fk_id_article_tag_article foreign key(id_article_ref)
	references articles(id_article) on delete restrict on update restrict;
	
alter table articles_tags add constraint fk_id_article_tag_tag foreign key(id_tag_ref)
	references tags(id_tag) on delete restrict on update restrict;   
Pour faire l'insertion des tags lors de l'écriture d'un nouvel article j'utilise deux requetes SQL :
- Une qui fait l insertion dans Articles
- Une qui fait l insertion des tags

Mon problème est que je ne sais pas comment remplir la table intermédiaire. Il faudrait que je récupère d'une part, l'identifiant du nouvel article, puis à chaque insertion ds la table Tags, l'identifiant du tag, et faire l'insertion.
Mes champs clés primaires étant en SERIAL, je ne vois pas comment récuperer l'identifiant créé lors de l'éxécution de la requête.

Merci ^^