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

MS SQL Server Discussion :

Récuper PK après update


Sujet :

MS SQL Server

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 22
    Par défaut Récuper PK après update
    Bonjour à tous.
    Voilà, comme indiqué dans le titre, j'aimerais récupérer l'id de la ligne que je viens de modifier mais je n'y parviens pas, j'arrive à récupérer l'id de la dernière ligne de la table par un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select IDENT_CURRENT('nomtable')
    mais ce n'est pas cela qui m'intéresse.
    J'aimerais donc savoir si ce que je cherche à faire est possible ou non et si oui comment.
    Merci d'avance.

  2. #2
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Congo-Brazzaville

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

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Par défaut
    Par principe, une clé primaire n'est pas modifiable donc vous n'avez qu'à le selectionner dans la base de données par un select basique !

    Quel est votre scripte d'update ?

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 22
    Par défaut
    désolé, je ne voulais pas dire que je modifiais la valeur de ma clé primaire (c'est une clé auto-incrémentée), une fois que j'effectue une modification sur un enregistrement, mon trigger update se lance et à partir de là j'aimerais récupérer l'id de l'enregistrement que je viens de modifier pour vérifier si la valeur de mon champ status est égale à '*'.

  4. #4
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Congo-Brazzaville

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

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Par défaut
    Attention, cette clé autoincrémentée est faites pour ne pas être modifiée.
    C'est vraiment contre-indiqué.

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 22
    Par défaut
    je ne veux pas modifier ma clé primaire mais mettre la valeur de cette clé dans une variable locale, ce qui me permettra de faire un select sur cet enregistrement en particulier (autrement l'enregistrement qui vient de subir une DML de type UPDATE).

  6. #6
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Congo-Brazzaville

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

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Par défaut
    Poste ta requête UPDATE et je vais voir.

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 22
    Par défaut
    voilà, c'est la dernière version de mon trigger
    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 Pere_Insert on Pere
        after update
        as
          DECLARE @PK_ID numeric
          DECLARE @logical_cascade int
    		-- pas ok car j’obtiens l’id du dernier enregistrement de la table
          SET @PK_ID = (Select IDENT_CURRENT('Pere'))
    		exec Procedure_Insert_Log 'Insert', 'Pere'
    		DECLARE @logical_cascade int
    		SET @logical_cascade = (select count(*) from Pere where Pere_Auto = @PK_ID and Status = '*')
          set @logical_name = (select Pere_Nom from Pere where Pere_Auto = @PK_ID)
    		if @logical_cascade = 1
    			begin
    				exec Procedure_Cascade_Fils_Pere @PK_ID
    			end
    j'aimerais que mon @PK_ID aie la valeur de l'id de l'enregistrement modifié

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    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 : 22 010
    Billets dans le blog
    6
    Par défaut
    Vore trigger est absolument idiot dans son écriture car il ne traitera que très partiellement l'UPDATE.

    En effet le trigger voit passer d'un seul coup TOUTES les lignes concernées par l'UDPATE.

    Par exemple si l'update consiste à faire :

    UPDATE MaTable
    SET Macolonne = 33

    Le trigger ne se déclenchera qu'une seule fois même si 1000000 lignes sont impactées par cet ordre.
    Par conséquent la présence de variable dans un trigger est une absurdité (puisque cela ne récupérera que les valeur de l'une des lignes (mais de laquelle ??? mystère !), et l'utilisation de curseur un cauchemar du fait de la lenteur.

    Il faut donc TOUJOURS un code SQL ensembliste dans un trigger.

    De plus vous appelez une procédure alors que le code de votre trigger est à l'intérieur de la transaction.

    Vous devriez entièrement re concevoir votre manière de développer. Vous courez au suicide dès que la base de données aura un certain volume....

    Le mieux serait de vous former...

    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/ * * * * *

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 22
    Par défaut
    je ne modifie pas plusieurs lignes à la fois mais une seule.
    j'aimerais simplement savoir si il y a moyen de récupérer l'id de cette ligne.

  10. #10
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    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 : 22 010
    Billets dans le blog
    6
    Par défaut
    Contrairement à ce que vous pensez, votre affirmation :
    je ne modifie pas plusieurs lignes à la fois mais une seule.
    est tout à fait absurde.

    Qu'est ce qui empêchera dans le futur (développement de votre appli) que l'UPDATE se produise sur plusieurs lignes ?

    Le seul moyen pour empêcher un update multiligne serait de mettre un trigger de rollback s'il y a plus d'une ligne dans la pseudo table INSERTED.

    C'est en partant de considération fausses que l'on pourrit bien les bases de données.

    Reconsidérez votre position ou passez vous de notre aide.

    Mais si vous voulez de l'aide, ayez au moins la gentillesse de nous expliquer plus clairement la finalité de votre demande. Autrement que voulez vous faire sur le plan logique et sémantique ? Quel est le but de ce code ? Que fait la proc Procedure_Cascade_Fils_Pere ???

    Et si possible donnez la description SQL de vos tables.

    Enfin par rapport à mon précédent post, vous pouriez faire en sorte de n'utiliser que des procédures stockées pour vos insertion, update, delete. Dans ce cas toute la logique est encapsulée dans la proc stock.

    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/ * * * * *

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 22
    Par défaut
    J'aimerais créer un trigger qui me permettrait de faire une suppression logique en cascade. j'entends par là que lorsqu'un utilisateur modifie un enregistrement (l'application est faite de telle façon qu'il est impossible pour un utilisateur de modifier plusieurs enregistrements en même temps) ou plus précisément, que je modifie le champ Status de cet enregistrement (ce champ indique si un enregistrement a été supprimé logiquement ou pas), s'il existe des enregistrements sur d'autres tables pointant vers l'enregistrement venant d'être supprimé logiquement, ces enregistrements seront supprimés à leur tour.

    Pour en revenir au code que j'avais posté plus tôt, je me doute qu'il n'est pas sans défaut, et j'apprécie fortement que l'on me fasse remarqué les problèmes que l'on y retrouve ou si la façon de m'y prendre est complètement fausse, qu'on m'explique clairement une meilleure façon de faire (ce qui me faire très plaisir d'apprendre des choses nouvelles puisque je débute dans le domaine).

    Dans ma base de données de test, on retrouve les tables suivantes :
    Pere, Mere, Fils, Fille et Log.

    Sur les trois premières tables nous retrouvons 3 triggers (for insert, for update, for delete) (par table évidement) qui me permette d'ajouter un enregistrement à la table log (qui soit dit en passant est une table circulaire) ou l'on retrouve la date à laquelle la DML qui a déclenché le trigger à été effectuée, le type de DML (Insert, Update ou Delete) et enfin le nom de la table ayant subi la DML (Pere, Mere ou Fils).
    A part cela, nous retrouvons également sur ces trois tables nous retrouvons à chaque fois un autre trigger for update qui sera donc déclenché à chaque fois que l'on modifie un enregistrement et qui n'appellera la procédure stockée que si l'on vient de modifier le champ Status (flag suppression logique). C'est donc ce trigger qui me pose problème car je n'arrive pas à récupérer l'id de l'enregistrement venant d'être modifié (je rappel encore une fois qu'un seul enregistrement est modifié à la fois).

    Pour prendre un exemple clair: on supprime logiquement un enregistrement Pere, le trigger ce déclenche, regarde si la modification apportée concerne le champ Status et si oui, lance une procédure stockée à laquelle on aurait passé comme argument, l'id du champ ayant subi la modification (si c'est possible) et vérifier dans la table Fils si un ou des enregistrements aie une clé étrangère Pere de valeur égale à l'id passé en argument et si oui, modifié le champ Status pour lui aussi le supprimer logiquement.

    Voici de nouveau le code de mon trigger for update:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    create trigger Pere_Update_Fils on Pere
    for update
    as
    	declare @pk_id numeric
    	declare @logical_cascade int
    	set @pk_id = (Select IDENT_CURRENT('Pere'))
    	set @logical_cascade = (select count(*) from Pere where Pere_Auto = @pk_id and Status = '*')
    	if @logical_cascade = 1
    		exec Procedure_Cascade_Fils_Pere @pk_id
    Ainsi que le code de ma procédure stockée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    create procedure Procedure_Cascade_Fils_Pere
    	@fk_id numeric
    as
    	--begin	
    		update Fils
    		set Status = '*'
    		from Pere p, Fils f
    		where f.Pere_Auto = @fk_id
    	--end
    	--begin
    		exec Procedure_Insert_Log 'Update', 'Fils'
    	--end
    Je retrouve également un problème dans cette procédure, qui je suis sûr vous l'avez compris est qui si plusieurs enregistrements sont modifiés, la procédure ne sera exécutée qu'une seule fois (ce qui est un problème qu'il faudrait que je résolve).

    Est-ce que mon problème est assez clair ou y a-t-il encore une zone de flou?

    Je tiens à préciser que j'apprécie l'aide apportée sur ce forum, c'est justement parce que j'éprouve des difficultés à résoudre mon problème, et pas forcément l'opportunité de suivre une formation approfondie que je viens demander votre aide et votre compréhension.

    Bien à vous.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 22
    Par défaut
    j'arrive maintenant à récupérer l'id dont j'ai besoin, il me reste encore à régler le problème de ma procédure qui ne s'exécute qu'une fois même si plusieurs enregistrements sont modifiés par table et après cela, je réécrirai le tout de manière pls 'acceptable'.

    en attendant voici ce que j'ai écrit :
    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
    17
    18
    19
    20
    21
    22
    23
    CREATE trigger Pere_Update_Fils on PERE
    for update
    as
    	declare @pk_id numeric
    	declare @logical_cascade int
    	set @pk_id = (select Top 1 Pere_Auto from inserted)
    	set @logical_cascade = (select count(*) from Pere where Pere_Auto = @pk_id and Status = '*')
    	if @logical_cascade = 1
    		exec Procedure_Cascade_Fils_Pere @pk_id
     
     
     
    ALTER procedure [dbo].[Procedure_Cascade_Fils_Pere]
    	@fk_id numeric
    as
    	--begin	
    		update Fils
    		set Status = '*'
    		where Pere_Auto = @fk_id and Status is null
    	--end
    	--begin
    		exec Procedure_Insert_Log 'Update', 'Fils'
    	--end
    parmis les modifications à apporter, je ferai, entre autre, de @fk_id et @logical_cascade, des procédures stockées.

  13. #13
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    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 : 22 010
    Billets dans le blog
    6
    Par défaut
    Votre explication est incompréhensible... je vous cite :
    on supprime logiquement un enregistrement Pere, le trigger ce déclenche, regarde si la modification apportée concerne le champ Status
    donc c'est de la suppression (DELETED) ou de la modif (UPDATE) ?

    mais tout ce travail devrait être fait dans le trigger sans aucun appel à une quelconque PS et en logique ensembliste....

    Merci de respecter ceci et de donner la description de vos table et un jeu d'essais SOUS FORME D'ORDRES SQL !
    http://www.developpez.net/forums/viewtopic.php?t=32668

    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/ * * * * *

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 22
    Par défaut
    comme expliqué un peu plus au, une suppression logique est un UPDATE, on flag le champ Status pour dire que l'enregistrement a été supprimé logiquement.
    pour ce qui est des procédures stockées appelées dans le trigger, on m'a demandé de faire de la sorte.

Discussions similaires

  1. Probleme vs 2005 apres update service pack 1
    Par mactwist69 dans le forum Visual Studio
    Réponses: 7
    Dernier message: 07/03/2009, 02h52
  2. [CS4] affichage de données après update
    Par nixax dans le forum Dreamweaver
    Réponses: 1
    Dernier message: 04/03/2009, 15h27
  3. Erreur XSL-1000 après update websphere 5.1
    Par rraph2003 dans le forum Websphere
    Réponses: 1
    Dernier message: 18/08/2008, 15h42
  4. Récuperer heure après appui sur bouton
    Par lg022 dans le forum VB.NET
    Réponses: 2
    Dernier message: 29/04/2008, 10h13
  5. Revenir en arriere apres Update
    Par ledjlale dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 18/04/2008, 15h32

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