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 :

Insertion dynamique


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2017
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2017
    Messages : 24
    Points : 11
    Points
    11
    Par défaut Insertion dynamique
    Bonjour,

    Je souhaite faire une insertion dynamique:

    Voici ma requête:

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    INSERT INTO TG_GPA (ID_TYPEDOC, ID_GPA)VALUES (
        (
            SELECT TGA0.ID_TYPEDOC FROM TG_GPA TGA0 WHERE TGA0.ID_GPA IN (
                SELECT TGA1.ID_GPA FROM TG_GPA TGA1 WHERE TGA1.ID_GPA=TGA0.ID_GPA
            ) AND TGA0.ID_GPA IN (31266, 42989, 42990, 311135)
        ),
        (SELECT MAX(ID_GPA+1) FROM TG_GPA))

    et j'ai l'erreur suivante :
    Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
    Sinon Quelqu'un peut il me donner une idée pour faire plusieurs insertions à la fois en utilisant des selects pour les valeurs à mettre?

    Merci d'avance.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 244
    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 244
    Points : 12 878
    Points
    12 878
    Par défaut
    Bonjour,
    Pour insérer plusieurs lignes en une fois, il ne faut pas utiliser VALUE:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    insert into matable (col1,col2)
    select colx,coly
    from autretable
    Ainsi ça fonctionne quel que soit le nombre de lignes renvoyées par le SELECT.

    Tatayo.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2017
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2017
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Merci pour votre réponse,

    quand je fais comme vous me dites j'ai une erreur de syntaxe pour la virgule

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INSERT INTO TG_GPA (ID_TYPEDOC, ID_GPA)
     
    												SELECT TGA0.ID_TYPEDOC FROM TG_GPA TGA0 WHERE TGA0.ID_GPA 
    												IN (SELECT TGA1.ID_GPA FROM TG_GPA TGA1 WHERE TGA1.ID_GPA=TGA0.ID_GPA) 
    																						AND TGA0.ID_GPA IN (31266, 42989, 42990, 311135)	, (SELECT MAX(ID_GPA+1) FROM TG_GPA)
    A savoir que dans la colonne ID_TYPEDOC, c'est une requête imbriquée qui insére et la colonne ID_GPA, c'est la requête qui y insére.

    Je suis sous SQLSERVER

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 244
    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 244
    Points : 12 878
    Points
    12 878
    Par défaut
    Le problème ici est le SELECT:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from table1
    where…, SELECT
    Cette syntaxe est incorrecte, la requête ne fonctionnera pas.
    Il faut que la requête renvoie autant de colonnes qu'en attend l'ordre INSERT, comme dans mon exemple (2 colonnes dans l'INSERT, 2 dans le SELECT), pas une de plus, pas une de moins.
    Comme ton INSERT attend 2 colonnes, ton SELECT doit en renvoyer 2.
    Le mieux ici est de passer par une CTE qui va renvoyer la "deuxième partie" de la requête.
    Je vois bien un truc du genre:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    with CTE as (select SELECT MAX(ID_GPA+1) as valeur FROM TG_GPA)
    insert into INSERT INTO TG_GPA (ID_TYPEDOC, ID_GPA)
    SELECT TGA0.ID_TYPEDOC,cte.valeur
    FROM TG_GPA TGA0
    cross join CTE
    WHERE TGA0.ID_GPA IN (31266, 42989, 42990, 311135)
    J'ai supprimé la sous-requête, car honnêtement je ne vois pas du tout à quoi elle sert. Pour chaque ligne de TableA, vérifier s'il existe une ligne de TableA avec le même id ? Chaque ligne a le même id qu'elle même…

    Tatayo.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2017
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2017
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    La sous requête elle permet de ne pas prendre n'importe quel ID_TYPEDOC, donc cette premiére requête doit me renvoyer l'id_typedoc correspondant à l'un des id_gpa de la liste (31266, 42989, 42990, 311135).

    Aprés exécution de votre requête j'ai une violation de PK: Violation of PRIMARY KEY constraint 'PK_TG_GPA'. Cannot insert duplicate key in object 'dbo.TG_GPA'. The duplicate key value is (1217824)

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 244
    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 244
    Points : 12 878
    Points
    12 878
    Par défaut
    Non, je maintiens que la sous-requête ne sert à rien. La seule restriction est dans le deuxième IN, avec la liste de valeurs.
    La première revient à faire une jointure de la table TG_GPA sur elle-même, comme ceci:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from TG_GPA as t0
    inner join TG_GPA as t1 on t0.idgpa = t1.idgpa
    La colonne IDGPA étant visiblement unique, ça revient à chercher pour chaque ligne si une ligne avec le même id existe. La réponse est oui: elle même.

    Concernant l'erreur, elle est "normale": la CTE ne renvoie qu'une seule valeur, donc l'insert ne fonctionne pas. il faudrait pour chaque ligne à insérer calculer un nouvel ID. L'idéal serait que l'ID en question soit de type auto-incrémenté, ce qui n'est visiblement pas le cas.

    J'avoue que je ne sais pas comment faire ici… peut-être avec un ROW_NUMBER pour numéroter les lignes, et ajouter cette valeur à celle renvoyée par la CTE...

    Tatayo.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2017
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2017
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Super, merci pour votre aide.

    Je vais essayer de voir quelle solution.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 785
    Points : 1 495
    Points
    1 495
    Par défaut
    Bonsoir,

    Je souscrit totalement à ce que tatayo a soulevé.

    Pour avancer pas à pas, il faudrait peut-être repousser à plus tard l'INSERT et se focaliser que le SELECT.
    Tant que le jeu de résultat n'est pas celui attendu on corrigera la requête.

    Que donne le résultat de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    with CTE as (select SELECT MAX(ID_GPA+1) as valeur FROM TG_GPA)
    /*insert into INSERT INTO TG_GPA (ID_TYPEDOC, ID_GPA)*/
    SELECT TGA0.ID_TYPEDOC,cte.valeur
    FROM TG_GPA TGA0
    cross join CTE
    WHERE TGA0.ID_GPA IN (31266, 42989, 42990, 311135)
    et, surtout, quel est le résultat espéré ?

  9. #9
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2017
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2017
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    Merci pour vos propositions, la proposition de tatyo est superbe, nous avons rendu le champ id_gpa sequenciel et le problème est résolu.
    Et donc la requête finale:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO TG_GPA (ID_TYPEDOC, ID_TIERS_COMMUN, BOO_PIECE_ORIGINE, BOO_EXPLOITABLE, DAT_TIERS_COMMUN )
    SELECT TGA.ID_TYPEDOC, TGA.ID_TIERS_COMMUN, TGA.BOO_PIECE_ORIGINE, TGA.BOO_EXPLOITABLE, TGA.DAT_TIERS_COMMUN
    FROM TG_GPA TGA
    WHERE TGA.ID_GPA IN (31266, 42989, 42990, 311135)

Discussions similaires

  1. Insertion dynamique de lignes en colonne dans un tableau
    Par lodan dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 23/03/2007, 07h18
  2. [MySQL] INSERT Dynamique
    Par nohik dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 03/03/2007, 09h22
  3. insertion dynamique de lignes dans un tableau
    Par loreleï85 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 22/06/2006, 17h32
  4. Réponses: 4
    Dernier message: 30/03/2006, 16h20
  5. [Tableaux] Insertion dynamique ligne dans un tableau
    Par masseur dans le forum Langage
    Réponses: 12
    Dernier message: 28/03/2006, 14h53

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