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 :

[TSQL] Problème exécution procédure stockée [2014]


Sujet :

Développement SQL Server

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Juin 2016
    Messages : 6
    Points : 3
    Points
    3
    Par défaut [TSQL] Problème exécution procédure stockée
    Bonjour à tous !

    Voici mon problème : Je souhaite mettre à jour une table A en fonction d'une table B uniquement si les données contenu dans A diffères de celle de B.
    J'ai lu qu'il n'était pas conseillé de mettre à jour une table à l'aide d'une procédure stockée mais étant néophyte en l matière je n'ai pas trouvé d'autre solution...
    Voici mon code :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
     
    ALTER PROCEDURE [dbo].[PS_RESTORE_PARAM_PROD] 
    	-- Add the parameters for the stored procedure here
    	@IdBase bigint 
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
    	DECLARE @Paragraphe varchar(50), @Variable varchar(50), @Valeur varchar(254), @Memo varchar(MAX), @Row uniqueidentifier, @IdBase_Connexion bigint
     
    	DECLARE curseur_save CURSOR FOR
    	SELECT Paragraphe, Variable,Valeur, Memo, Rowguid, Id_Base from dbo.Connexion_Serveur where Id_Base = @IdBase
     
    	OPEN curseur_save
     
    	FETCH curseur_save into @Paragraphe,@Variable, @Valeur, @Memo, @Row, @IdBase_Connexion
     
    	WHILE @@FETCH_STATUS = 0
    	BEGIN
     
    		DECLARE @ParagraphePROD varchar(50), @VariablePROD varchar(50), @ValeurPROD varchar(254), @MemoPROD varchar(MAX), @RowPROD uniqueidentifier
    		DECLARE curseur_PROD CURSOR FOR
    		SELECT Paragraphe, Variable,Valeur, Memo, Rowguid from [ATH].[dbo].[CONNEXION_SERVEUR]
     
    		OPEN curseur_PROD
     
    		FETCH curseur_PROD into @ParagraphePROD,@VariablePROD, @ValeurPROD, @MemoPROD, @RowPROD
     
    		WHILE @@FETCH_STATUS = 0
    		BEGIN
     
    			IF @Row = @RowPROD 
    			BEGIN
    				IF @Paragraphe != @ParagraphePROD
    				SET @ParagraphePROD = @Paragraphe
     
    				CLOSE curseur_PROD
    				DEALLOCATE curseur_PROD
    			END
     
    		END
     
    	END
     
    END
    CLOSE curseur_save
    DEALLOCATE curseur_save
    Je m'excuse d'ors et déjà auprès de ceux qui vont lire mon code car ça risque de leur faire mal aux yeux
    Et si vous souhaitez plus de précision n'hésitez pas à me faire signe

    Cordialement,

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 802
    Points
    30 802
    Par défaut
    Je pense que la commande MERGE devrait répondre de manière beaucoup plus élégante et efficace à ton besoin.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Juin 2016
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    En effet ça me semble bien mieux au première abord.
    Je vais essayer ça, merci bien.

  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
    Bonjour,

    Juste une précision sur ce point :
    Citation Envoyé par Heisenberg5625 Voir le message
    J'ai lu qu'il n'était pas conseillé de mettre à jour une table à l'aide d'une procédure stockée
    Ce n'est pas le fait d'utiliser une procédure stockée, ce qui est au contraire plutôt une bonne pratique.
    Ce qui est déconseillé, c'est d'utiliser des curseurs comme vous le faites. Ce ceux eux qui nuisent aux performances dans votre cas.

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Juin 2016
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    Merci pour cette précision aieuuuu.

    J'ai essayé le MERGE mais j'ai une SQLException qui est levée du côté de mon application : "Une exception non gérée du type 'System.Data.SqlClient.SqlException' s'est produite dans System.Data.dll

    Informations supplémentaires : La cible d'une instruction MERGE ne peut pas être une table distante, une vue distante ou une vue sur des tables distantes."

    Voici le MERGE que j'ai fait :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    USE [Migration_Donnees]
    GO
    /****** Object:  StoredProcedure [dbo].[PS_RESTORE_PARAM_PROD]    Script Date: 20/06/2016 16:40:01 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    -- =============================================
    -- Author:		<Author,,Name>
    -- Create date: <Create Date,,>
    -- Description:	<Description,,>
    -- =============================================
    ALTER PROCEDURE [dbo].[PS_RESTORE_PARAM_PROD] 
    	-- Add the parameters for the stored procedure here
    	@IdBase bigint
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
    	CREATE TABLE #Con ([Paragraphe] varchar(50), [Variable] varchar(50), [Valeur] varchar(254), [Memo] varchar(MAX), [Rowguid] uniqueidentifier, [Id_Base] bigint)
    	BEGIN
    		INSERT INTO #Con
    		([Paragraphe], [Variable], [Valeur], [Memo], [Rowguid], [Id_Base])
    		SELECT
    		[Paragraphe], [Variable], [Valeur], [Memo], [Rowguid], [Id_Base]
    		FROM
    		[dbo].[Connexion_Serveur]
    		WHERE Id_Base = @IdBase
    	END
    	BEGIN
     
    		MERGE [ATH].[dbo].[CONNEXION_SERVEUR] as prod
    		USING #Con
    		ON (prod.rowguid = #Con.Rowguid)
    		WHEN MATCHED THEN
    		UPDATE SET prod.Paragraphe = #Con.paragraphe;
     
    	END
    END

  6. #6
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 775
    Points
    6 775
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Il me semble que le using ne s'utilise qu'avec une requête.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MERGE [ATH].[dbo].[CONNEXION_SERVEUR] as T
    USING ( SELECT *
              FROM #Con ) AS S
      ON T.rowguid = S.Rowguid
    WHEN MATCHED THEN
    UPDATE SET Paragraphe = S.paragraphe;

    Par contre je ne comprends pas. Dans la première version il y a 2 curseurs qui s'imbriquent, comment 1 seul merge? (vu le code, un update devrait suffir même)

    Sinon, il est possible de se passer de la #Con en utilisant la requête qui la constitue dans la source du merge.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    MERGE [ATH].[dbo].[CONNEXION_SERVEUR] as T
    USING ( SELECT [Paragraphe], [Variable],
                   [Valeur]    , [Memo]    ,
                   [Rowguid]   , [Id_Base]
              FROM [dbo].[Connexion_Serveur]
             WHERE Id_Base = @IdBase) AS S
      ON T.rowguid = S.Rowguid
    WHEN MATCHED THEN
    UPDATE SET Paragraphe = S.paragraphe;

    Cordialement,
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  7. #7
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Juin 2016
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    En effet le using s'utilise que dans une requête et un UPDATE suffit.

    Merci pour vos réponses !

  8. #8
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Attention avec les requêtes MERGE :

    - MERGE donne l'impression que le traitement se fait d'un seul tir, comme on le pense avec INSERT, UPDATE ou DELETE. Or intrinsèquement, le moteur réalise les opérations une par une;
    - Si la table cible du MERGE a des déclencheurs, et que le déclencheur peut s'exécuter sur plus d'un type de DML (ex FOR INSERT, UPDATE), le déclencheur s'exécute plusieurs fois, ce qui prouve d'ailleurs ce qui est ci-dessus :

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    CREATE TABLE zeTable
    (
    	i tinyint
    )
    GO
     
    INSERT INTO zeTable (i) VALUES (4)
     
    CREATE TRIGGER TR_A_IU_zeTable
    	ON zeTable
    	FOR INSERT, UPDATE
    AS
    BEGIN
    	SET NOCOUNT ON
     
    	PRINT 'Entering the trigger'
     
    	IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted)
    	BEGIN
    		PRINT 'Processing INSERT - ' + CAST(SYSDATETIME() AS char(27));
    	END
     
    	IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
    	BEGIN
    		PRINT 'Processing UPDATE - ' + CAST(SYSDATETIME() AS char(27));
    	END
     
    	IF NOT EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
    	BEGIN
    		PRINT 'Processing DELETE - ' + CAST(SYSDATETIME() AS char(27));
    	END
    END
    GO
     
    MERGE	INTO dbo.zeTable AS TGT
    USING	(
    		SELECT 0 AS i
    		UNION ALL SELECT 1
    		UNION ALL SELECT 2
    		UNION ALL SELECT 3
    		UNION ALL SELECT 4
    		UNION ALL SELECT 5
    		UNION ALL SELECT 6
    	) AS SRC
    		ON SRC.i = TGT.i
    WHEN	MATCHED THEN UPDATE
    		SET i = SRC.i
    WHEN	NOT MATCHED BY TARGET THEN INSERT(i) VALUES (SRC.i)
    WHEN	NOT MATCHED BY SOURCE THEN DELETE;
    On a :

    Entering the trigger
    Processing INSERT - 2016-06-28 14:19:57.4692079
    Entering the trigger
    Processing UPDATE - 2016-06-28 14:19:57.4692079
    Attention donc à bien tester, notamment la concurrence.
    Il est possible que dans certaines situations de concurrence d'exécution du MERGE, on doive sérialiser son exécution, soit avec HOLDLOCK, soit avec SET TRANSACTION ISOLATION LEVEL SERIALIZABLE.

    @+

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

Discussions similaires

  1. iBatis/Oracle : problème exécution procédure stockée
    Par marinew dans le forum Accès aux données
    Réponses: 6
    Dernier message: 28/02/2011, 15h31
  2. Réponses: 1
    Dernier message: 17/07/2006, 17h08
  3. [VB.NET]Performance exécution procédure stockée
    Par Franck2mars dans le forum Windows Forms
    Réponses: 3
    Dernier message: 29/05/2006, 16h11
  4. [SQL SERVER 2K]Droits d'exécution procédure stockée
    Par Franck2mars dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 16/05/2006, 15h01
  5. Problème de procédure stockée
    Par Sorcier157 dans le forum Langage SQL
    Réponses: 9
    Dernier message: 17/03/2005, 17h57

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