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 SQL Discussion :

Problème requête UPDATE sur decalage d'index


Sujet :

Langage SQL

  1. #1
    Membre expérimenté
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Points : 1 307
    Points
    1 307
    Par défaut Problème requête UPDATE sur decalage d'index
    Bonjour à tous,

    Pour faire simple, j'ai une table avec des données que j'ordonne via un champ "mon_index" unique (qui n'est pas clé primaire de la table). Ce champ contient donc des valeurs consécutives.
    Je souhaite déplacer des éléments, et reconstruire le champ "mon_index".
    Exemple:
    J'ai dans ma table les valeurs 1,2,3,4,5,6,7,8,9,10 et je souhaite prendre la ligne "9" et l'insérer entre la "2" et la "3"
    1) J'attribue à la ligne "9" une valeur qui 'est jamais utilisée "-100"
    2) Je décale les lignes 3 à 8 de 1 cran
    3) je réattribue à ma ligne "-100" la valeur "3"

    Sur la papier ça fonctionne, le problème est à l'étape (2) ou j'effectue un UPDATE:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE matable
    SET mon_index = (mon_index+1)
    WHERE mon_index >= 3
    AND mon_index < 9
    J’exécute cette requête sur mon jeu de données (-100,1,2,3,4,5,6,7,8,10) et cette requête me renvoi "la valeur d'une clé dupliquée rompt la contrainte unique « uk_XXXXXX ». ".


    Je suppose que c'est parce que la requête s’exécute ligne par ligne, et qu'a un moment il y a une valeur dupliquée?
    N'y a t'il pas moyen d’exécuter la requête "en une fois", et de vérifier la contrainte d'unicité qu'après exécution?

    Je ne sais pas si je suis très clair! Mes tables sont un peu plus complexe, j'ai essayer de simplifier au maximum pour illustrer mon cas.

    Pour info, je suis sous PostgreSQL 8.4

    Merci d'avance pour votre retour!
    Ce que l'on apprend par l'effort reste toujours ancré plus longtemps...

  2. #2
    Membre averti
    Homme Profil pro
    Ingénieur en études décisionnelles
    Inscrit en
    Février 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur en études décisionnelles

    Informations forums :
    Inscription : Février 2013
    Messages : 134
    Points : 351
    Points
    351
    Par défaut
    Bonjour,

    Je passerais par une table temporaire avec deux colonnes : mon_index et mon_index_maj.
    Je te laisse le soin de la créer, je ne connais pas la syntaxe Postgres. Ensuite, tu l'alimentes, puis tu update à partir de cette table.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    insert into Test
    select mon_index, mon_index from matable ;
     
    update Test
    SET mon_index_maj = (mon_index+1)
    WHERE mon_index >= 3
    AND mon_index < 9;
     
    update Test
    SET mon_index_maj = 3
    WHERE mon_index = 9;
     
    update matable
    from Test
    set mon_index = mon_index_maj
    where matable.mon_index = Test.mon_index;
    Bonne journée.

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 134
    Points : 38 557
    Points
    38 557
    Billets dans le blog
    9
    Par défaut
    Autre possibilité : supprimer temporairement la contrainte unique sur l'index mais quelle est la vocation fonctionnelle exacte de cette colonne index ?
    Si le but est de connaitre la chronologie des créations, ce n'est pas la bonne façon de faire

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 766
    Points : 52 561
    Points
    52 561
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par sat83 Voir le message
    J’exécute cette requête sur mon jeu de données (-100,1,2,3,4,5,6,7,8,10) et cette requête me renvoi "la valeur d'une clé dupliquée rompt la contrainte unique « uk_XXXXXX ». ".
    Hélas PostGreSQL ne sait pas faire des opérations ensembliste correctement et agit ligne à ligne ce qui est stupide. N'importe quel bon SGBDR (Oracle, SQL Server; IBM DB2...) aurait agit sans problème. Néanmois dans PG il y a possibilité de truander le système en faisant une contrainte déferrable...
    A me lire : http://blog.developpez.com/sqlpro/p1...bd_relationn_1

    Je suppose que c'est parce que la requête s’exécute ligne par ligne, et qu'a un moment il y a une valeur dupliquée?
    N'y a t'il pas moyen d’exécuter la requête "en une fois", et de vérifier la contrainte d'unicité qu'après exécution?

    Je ne sais pas si je suis très clair! Mes tables sont un peux plus complexe, j'ai essayer de simplifier au maximum pour illustrer mon cas.

    Pour info, je suis sous PostgreSQL 8.4

    Merci d'avance pour votre retour!
    Néanmoins ce que vous faite est stupide, car il n'y a aucun ordre particulier des lignes dans une table quelque soit le SGBDR !!!

    A me lire : http://blog.developpez.com/sqlpro/p5..._sont_des_ense

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Membre expérimenté
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Points : 1 307
    Points
    1 307
    Par défaut
    Néanmoins ce que vous faite est stupide
    Merci! Très aimable!

    Hélas PostGreSQL ne sait pas faire des opérations ensembliste correctement et agit ligne à ligne
    Comme j'ai la réponse à ma question, je passe en résolu.

    Vu que le nombre de lignes à traiter n'est pas très important (<25), je contourne le problème en effectuant une boucle et N requêtes UPDATE successives.
    Je voulais éviter cette solution pas très optimisée, mais ça ira très bien dans mon cas!

    Merci en tout cas à ceux qui ont pris le temps de me répondre!
    Ce que l'on apprend par l'effort reste toujours ancré plus longtemps...

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    Citation Envoyé par SQLpro Voir le message
    Néanmoins ce que vous faite est stupide, car il n'y a aucun ordre particulier des lignes dans une table quelque soit le SGBDR !!!
    A +
    Je ne vois pas trop ce qu'il y a de stupide ici.
    Je comprends bien que sans spécifier d'ordre dans un SELECT, rien ne permet de savoir dans quel ordre vont arriver les lignes.
    C'est justement parce qu'il n'y a pas d'ordre qu'une colonne "rang" peut être nécessaire, si on veut pouvoir forcer un ordre de tri via un ORDER BY sur cette colonne.
    Et si, dans cet ordre, on veut "insérer" une ligne entre deux autres, il faut bien un moyen renuméroter ce rang dans les lignes.

    J'ai un cas concret, avec une table qui contient une liste d'application (pour un portail applicatif mobile, qui récupère cette liste via un webservice). L'utilisateur veut pouvoir choisir l'ordre d'affichage des applications. Donc il me faut pouvoir stocker cet ordre, et surtout changer l'ordre d'affichage, donc "renuméroter" les lignes, comme dans la demande initiale.

    On me rétorquera qu'on peut trier les lignes dans l'application, mais c'est déplacer le problème: il faut quand même stocker le rang dans la base, donc dans les lignes de la table, et il faut pouvoir "décaler" des lignes pour en "insérer" une à un rang particulier.

    A moins d'utiliser un float, et de donner comme rang à la ligne à insérer la moyenne des rangs des deux lignes qui l'encadre ?

    Mais s'il y a une méthode plus "propre", je suis preneur.

    Tatayo.

  7. #7
    Membre expérimenté
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Points : 1 307
    Points
    1 307
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Mais s'il y a une méthode plus "propre", je suis preneur.
    Moi aussi, si jamais quelqu'un à une autre idée!
    Ce que l'on apprend par l'effort reste toujours ancré plus longtemps...

  8. #8
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Utiliser Oracle, SQL Server ou DB2
    On ne jouit bien que de ce qu’on partage.

  9. #9
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 766
    Points : 52 561
    Points
    52 561
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Bonjour,


    Je ne vois pas trop ce qu'il y a de stupide ici.
    Je comprends bien que sans spécifier d'ordre dans un SELECT, rien ne permet de savoir dans quel ordre vont arriver les lignes.
    C'est justement parce qu'il n'y a pas d'ordre qu'une colonne "rang" peut être nécessaire, si on veut pouvoir forcer un ordre de tri via un ORDER BY sur cette colonne.
    Et si, dans cet ordre, on veut "insérer" une ligne entre deux autres, il faut bien un moyen renuméroter ce rang dans les lignes.

    J'ai un cas concret, avec une table qui contient une liste d'application (pour un portail applicatif mobile, qui récupère cette liste via un webservice). L'utilisateur veut pouvoir choisir l'ordre d'affichage des applications. Donc il me faut pouvoir stocker cet ordre, et surtout changer l'ordre d'affichage, donc "renuméroter" les lignes, comme dans la demande initiale.
    Utilisez un FLOAT ou un décimal et intercalez au besoin.

    On me rétorquera qu'on peut trier les lignes dans l'application, mais c'est déplacer le problème: il faut quand même stocker le rang dans la base, donc dans les lignes de la table, et il faut pouvoir "décaler" des lignes pour en "insérer" une à un rang particulier.

    A moins d'utiliser un float, et de donner comme rang à la ligne à insérer la moyenne des rangs des deux lignes qui l'encadre ?

    Mais s'il y a une méthode plus "propre", je suis preneur.

    Tatayo.
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

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

Discussions similaires

  1. [C#] Problème requête update via OdbcDataAdpter
    Par LE NEINDRE dans le forum ASP.NET
    Réponses: 12
    Dernier message: 16/06/2006, 11h52
  2. Problème de update sur un datagrid
    Par jbr_85 dans le forum Accès aux données
    Réponses: 1
    Dernier message: 31/05/2006, 14h57
  3. Problème Requête UPDATE (ou pas)
    Par mastasushi dans le forum Access
    Réponses: 7
    Dernier message: 03/05/2006, 08h42
  4. [MySQL] problème requête UPDATE
    Par oceane751 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 23/10/2005, 18h28

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