IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

SQL : insérer en milieu de table


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut SQL : insérer en milieu de table
    Bonjour

    J'ai une table ordonnée dans une base de donnée et je dois pouvoir insérer au milieu de la table une nouvelle ligne, connaissant les deux valeurs entre lesquelles la placer :
    • 1=> valeur 1
    • insérer la nouvelle ligne "valeur 1b"
    • 2=> valeur 2
    • 3=> valeur 3
    • 4=> valeur 4

    Le problème est alors qu'il faut décaler les ordre d'un. Or la table contient environ 7000 valeurs, donc il y a un temps de latence de 20s à chaque insertion, ce qui est très pénible. De plus, je n'ai pas trouvé de requête qui permette d'insérer après l'id n comme on a en python : insert(index)
    Le but est d'arriver à :

    • 1=> valeur 1
    • 2=> valeur 1b
    • 3=> valeur 2
    • 4=> valeur 3
    • 5=> valeur 4


    Connaissez vous des méthodes autres qu'une boucle sur les 7000 valeurs avec une 7000 requêtes ?
    Merci beaucoup
    Mon code pour l'instant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    //on récupère toutes les entrées à modifier
    $req4 = $bdd->prepare('SELECT * FROM decoupage WHERE ordre>=:ordre');
    $req4->execute(array('ordre'=>$ordre_debut));
    while ($donnees4 = $req4->fetch())
    {
    	// on récupère et on indente
    	$i=$donnees4['ordre'];
    	$j=$donnees4['ordre']+1;
    	// on modifie
    	$req2 = $bdd->prepare('UPDATE decoupage SET ordre=:ordre WHERE ordre=:ordre2');
    	$req2->execute(array('ordre'=>$j, 'ordre2'=>$i));
    }

  2. #2
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Comment fais-tu pour déterminer la place du nouvel enregistrement ?

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut
    C'est une donnée : je connais $ordre juste avant. J'incrémente donc tous ceux au dessus pour faire la place au petit nouveau, puis je l'insère à cet endroit

  4. #4
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Oui mais qu'est-ce qui fait que cet "ordre" a telle ou telle valeur ? Pourquoi insérer en 1B plutôt qu'en 2B ?

  5. #5
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Il faut commencer par modifier l'ordre de la plus grande valeur vers la plus petite afin d'éviter des clés en double si on partait du plus petit vers le plus grand.

    Supposons que tu veuilles insérer en 11ème position.

    D'abord il faut décaler les enregistrements à partir du 11ème (donc supérieur au 10ème ou supérieur ou égal au 11ème)

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    update `table` set `nombre`=`nombre`+1 
    where nombre > 10
    order by nombre desc

    ou
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    update `table` set `nombre`=`nombre`+1 
    where nombre >= 11
    order by nombre desc

    Nom : Capture20181207_001.JPG
Affichages : 249
Taille : 20,2 Ko

    Et une fois la modification faite tu insères en 11ème position.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut
    L'application décrite ici consite en une liste auquel l'utilisateur peut ajouter des données où il le souhaite. Si par exemple la liste est ce poème

    • Un éclair... puis la nuit ! - Fugitive beauté (ordre = 0, id=0)
    • Dont le regard m'a fait soudainement renaître, (ordre = 1, id=1)
    • Ne te verrai-je plus que dans l'éternité ? (ordre = 2, id=2)
    • Ailleurs, bien loin d'ici ! trop tard ! jamais peut-être ! (ordre = 3, id=3)
    • Ô toi que j'eusse aimée, ô toi qui le savais ! (ordre = 4, id=4)
    • Charles Baudelaire (ordre = 5, id=5)


    Mais l'utilisateur a oublié ce vers : "Car j'ignore où tu fuis, tu ne sais où je vais," à l'avant dernière position. Il décide alors de le rajouter, en précisant la position, que je récupère dans $ordre (à savoir ici 3 : juste après "ailleurs..." et alors, il faut rajouter dans la liste le vers, et décaler les suivant
    • Un éclair... puis la nuit ! - Fugitive beauté (ordre = 0, id=0)
    • Dont le regard m'a fait soudainement renaître, (ordre = 1, id=1)
    • Ne te verrai-je plus que dans l'éternité ? (ordre = 2, id=2)
    • Ailleurs, bien loin d'ici ! trop tard ! jamais peut-être ! (ordre = 3, id=3)
    • Car j'ignore où tu fuis, tu ne sais où je vais, (ordre = 4, id=6)
    • Ô toi que j'eusse aimée, ô toi qui le savais ! (ordre = 5, id=4)
    • Charles Baudelaire (ordre = 6, id=5)



    Par ailleurs, j'ai fais une erreur en recopiant a fonction, il faut en effet ne pas modifier tout, donc c'est bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    //on récupère toutes les entrées à modifier
    $req4 = $bdd->prepare('SELECT * FROM decoupage WHERE ordre>=:ordre');
    $req4->execute(array('ordre'=>$ordre_debut));
    while ($donnees4 = $req4->fetch())
    {
    	// on récupère et on indente
    	$i=$donnees4['id'];
    	$j=$donnees4['ordre']+1;
    	// on modifie
    	$req2 = $bdd->prepare('UPDATE decoupage SET ordre=:ordre WHERE id=:id');
    	$req2->execute(array('ordre'=>$j, 'id'=>$i));
    }
    Ainsi l'ordre n'est pas modifié de proche en proche mais bien une seule fois.

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut
    Sinon j'ai aussi un code comme celui
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    //De la dernière ligne à celle juste après, on descend
    for ($i=$count-1; $i>=$ordremax; $i--) { 
    	$j = $i + 1;
    //on modifie
    	$req = $bdd->prepare('UPDATE decoupage SET ordre=:ordre WHERE ordre=:ordreprecedent');
    	$req->execute(array('ordre'=>$j, 'ordreprecedent'=>$i));
    }
    Là, on n'a pas non plus de modification récursive : on utilise i-- décroissant et j=i+1 croissant.

  8. #8
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 104
    Par défaut
    Pour moi il y a un problème de conception. Théoriquement, un jeu de données dans une table SQL n’est pas ordonné (en pratique il est toujours stocké dans un certain ordre, mais c’est de la mécanique interne et on n’est pas censé le savoir). On ordonne quand on fait un SELECT, et au dernier moment on peut ajouter une variable de « comptage ».
    Du coup je ferais comme ça :
    1. on garde si on veut la colonne id, mais on ne s’en sert plus
    2. on ajoute un index (si ce n’est pas déjà le cas) sur la colonne ordre
    3. Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      SET @n := 0;
      SELECT decoupage.*, @n := @n + 1 AS n
          FROM decoupage 
          ORDER BY ordre;


    Dans la pratique, PDO nous oblige en général à faire les requêtes une seule à la fois, donc on peut remplacer la séquence SETSELECT par un bête JOIN :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT decoupage.*, @n := @n + 1 AS n
        FROM decoupage INNER JOIN (SELECT @n := 0) AS subquery
        ORDER BY ordre;

    Une idée piquée à badaze… Ce n’est pas la première fois

    Edit : mais je crois que la proposition de badaze dans son post #5 sera plus efficace.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 07/07/2011, 11h05
  2. Réponses: 3
    Dernier message: 30/06/2011, 14h11
  3. [SQL] Insérer des données dans une table
    Par wonga dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 01/08/2007, 13h00
  4. [SQL]insérer le total d'une requete dans une table
    Par toadnam dans le forum Requêtes et SQL.
    Réponses: 9
    Dernier message: 31/05/2007, 12h17
  5. Réponses: 2
    Dernier message: 28/09/2006, 11h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo