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

Développement SQL Server Discussion :

Opération except retourne une ligne null


Sujet :

Développement SQL Server

  1. #1
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2008
    Messages : 102
    Points : 78
    Points
    78
    Par défaut Opération except retourne une ligne null
    bonjour tout ou presque est dans le titre

    j'ai créé un trigger sur une table après update pour inserer une ligne dans une table test (table constitué de 2 champs, un champ index en incrément automatique et un champ ID)

    la commande est la suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    insert into test select ID from deleted except select ID from inserted
    cette commande est sensé me renvoyé une ligne avec la valeur de l'ID qui a changé après l'update. Or voila cette requête me revoie deux ligne dont la première a pour résultat NULL et la deuxième avec l'ID attendu.

    Ma question est pourquoi ai-je cette première ligne avec NULL dedans et comment je peut m'en débarrasser pour avoir juste ma ligne avec l'id dedans

    merci d'avance

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Je pense que votre analyse n'est pas bonne : tel que vous le décrivez, votre requête devrait toujours vous renvoyer un ensemble vide...
    A moins que vous ne mettiez a jour la colonne ID... est-ce le cas ? La Colonne Id est-elle nullable ?

    Postez le code du trigger complet, et les requêtes d'update testées et les DDL des tables

  3. #3
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2008
    Messages : 102
    Points : 78
    Points
    78
    Par défaut
    bonjour,

    En effet ce trigger se déclenche dans le cadre d'une mise a jour du champs ID, juste avant je fait un IF UPDATED(ID) BEGIN . . . END.
    Je ne veut en aucun cas exécuter se trigger s'il n'y a pas lieu
    Le But de se trigger est de récupéré une pseudo table avec 2 ID, le supprimer et le nouveau et de stoker cela dans une table Test (pour plus tard crée une table d'audit.
    Comme je ne met a jour qu'un seul champs a la fois dans la logique la requête devrais me retourné une seule ligne hors a chaque fois elle me retourne 2 lignes et systématiquement la 1ere contient les 2 champs à null et la deuxième avec le résultat escompter.
    Le champs de la table sur laquelle porte le trigger est NOT NULL et mon souci et que les champs de la table test de destination non plus donc cette ligne avec des résultats null m'embête fortement et surtout je ne comprend pas pourquoi elle est généré.

    La table Test a 3 champs maintenant
    Idx int PK INDENTITY AUTO INCREMENT
    Del_ID NCHAR(13) NOT NULL
    Ins_ID NCHAR(13) NOT NULL

    voici le code du trigger qui est programmé pour se déclenché AFTER UPDATE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    IF UPDATED(ID)
    BEGIN
    insert into Test
    select * from 
    (
    (select ID as DelID from deleted except select ID from inserted) as Del)
    (select ID as InsID from inserted except select ID from deleted) as Ins) 
    ) as Maj
    END
    merci d'avance

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    C'est ça votre trigger ? heu... ça compile ça ?

    Si vous ne pouvez pas poster les vrai code du trigger, reproduisez le problème avec des noms non significatifs et postez l'exemple complet...

    Parce que si vous enlevez ou modifiez la moitié des lignes d'un code qui fonctionne mal, ça fonctionne encore moins bien et on aura beaucoup de mal a vous aider !

  5. #5
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2008
    Messages : 102
    Points : 78
    Points
    78
    Par défaut
    bah il y a a peu près tout la a part bien sur l'en-tete de création du trigger sur la table mais sinon ya tout est oui ça compile

    alors si je respecte pas quelque chose ou si je ne fait pas les chose correctement veuillez m'excuser je débute en transact sql et le seul moyen pour me former c'est le net et les livres, hors je ne trouve rien sur les tables deleted et inserted qui pourrai m'aider dans le cas présent

    sinon le code c'est vraiment celui-la, hors mis l'en-tête de création ou de modification du trigger et la définition de l'action je pourrai le réécrire autrement du genre

    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
     
    CREATE TRIGGER [Insert_ID_Into_Test]
    ON [Products]
    AFTER UPDATE
    AS
    IF UPDATE(ID)
    BEGIN
    INSERT INTO Test(Del_ID, Ins_ID)
    SELECT * FROM
    (
    (SELECT ID AS DelID FROM deleted except SELECT ID FROM inserted),
    (SELECT ID AS InsID FROM inserted except SELECT ID FROM deleted)
    ) 
     
    END
    mais ça change rien le souci de la ligne avec les valeur null est toujours la

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    heu si, ça change tout justement (vous avez corrigé trois erreurs dans votre deuxième code), puisque maintenant on comprend un peu mieux ce que vous essayez de faire

    maintenant que votre trigger est lisible, on comprend mieux le problème :

    lorsque vous faite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (SELECT ID AS DelID FROM deleted except SELECT ID FROM inserted)
    Vous pouvez avoir un résultat vide

    Mais quand vous faites (d’ailleurs je crois qu'il manque un SELECT dans votre code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT
    (SELECT ID AS DelID FROM deleted except SELECT ID FROM inserted),
    (SELECT ID AS InsID FROM inserted except SELECT ID FROM deleted)
    si une des requêtes renvoi une ligne, mais pas l'autre, vous aurez null dans colonne correspondante. Votre NULL vient de là je pense. En fait votr EXCEPT ne renvoi rien, mais englobé dans votre pseudo table, ça devient un NULL

    Cela dit, votre trigger est faux, car vous supposez qu'il n'y aura que les lignes de votre table seront mises à jour une par une, mais ce ne sera pas forcément toujours le cas.

    Est-ce que ID est la clef primaire de votre table Products ?
    si oui :
    - pourquoi changez vous les ID ?
    - Avez vous une clef alternative dans cette table ?

  7. #7
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2008
    Messages : 102
    Points : 78
    Points
    78
    Par défaut
    En effet ID et ma clé primaire ici et j'ai une clé alternative (secondaire) de type int en auto incrément qui ne change jamais.
    Pourquoi je change ma PK donc mon ID car il arrive que le produit soit le même mais que ça référence peu changer à un moment ou un autre. Ce champ et ma PK car l'ID doit être unique et surtout c'est que ce champ est référencé par des FK dans d'autre table.

  8. #8
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    ok, on commence à y voir plus clair.

    votre clef int en auto incrément devrait plutôt être la clef primaire, plutôt que la référence du produit qui, non seulement peu changer, mais en plus est en NCHAR(13) visiblement...
    Rien ne vous empêche cependant de mettre une contrainte d'unicité sur la référence du produit, mais l'utiliser comme clef primaire n'est pas une bonne idée.

    Pour votre problème, votre trigger peut s’écrire comme ceci (pas testé):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE TRIGGER [Insert_ID_Into_Test]
    ON Products
    AFTER UPDATE
    AS
    	INSERT INTO Test(Del_ID, Ins_ID)
    		SELECT D.ID, I.ID
    		FROM	Deleted D
    		INNER JOIN Inserted I
    			ON		I.ClefAlternative = D.ClefAlternative
    		WHERE	D.ID <> I.ID

Discussions similaires

  1. Nombre de ligne que retourne une ligne
    Par newmar dans le forum Hibernate
    Réponses: 7
    Dernier message: 15/05/2008, 12h40
  2. Afficher une ligne null ou vide dans un champ
    Par axamen dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 12/03/2008, 18h30
  3. Réponses: 6
    Dernier message: 30/08/2007, 16h47
  4. retourner une valeur à null ou 0
    Par pimpmyride dans le forum Requêtes
    Réponses: 6
    Dernier message: 06/06/2007, 17h18
  5. Retourner une ligne d'un tableau à 2dimensions
    Par allserv dans le forum ASP
    Réponses: 4
    Dernier message: 28/05/2007, 09h34

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