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 :

Procédure de copie générique entre bases semblables


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Par défaut Procédure de copie générique entre bases semblables
    Bonjour

    avec un ensemble de 5 bases identiques
    je voudrais généralisée la procedure stockée de copie suivante
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
     
    CREATE PROCEDURE [dbo].[Usp_Dev_Devpart_Copy] 
    	@ID_TO_COPY INT,
    	@ID_DEST INT,
    	@MODE char(2),
    	-- FA = Fils ainé
    	-- FC = Fils cadet
    	-- GF = Grand Frère
    	-- PF = Petit frère
    	@NEW_DPT_ID INT OUTPUT
    AS
    BEGIN
     
    	DECLARE
    		@ERROR INT,
    		@ROWCOUNT INT,
    		@TRANCOUNT INT,
    		@NBE INT,
    		@DEV_ID_SRC INT,
    		@DPT_PID_SRC INT,
    		@DPT_ORD_SRC INT,
    		@DPS_ID_SRC INT,
     
    		@DEV_ID_DEST INT,
    		@DPT_PID_DEST INT,
    		@DPT_ORD_DEST INT,
     
    		@DPT_FAMILLE_DEST dbo.D_FAMILLE_ARTICLE,
    		@DPT_SFAMILLE_DEST dbo.D_FAMILLE_ARTICLE,
    		@DPS_ID_DEST INT,
     
    		@NEW_ORD INT,
    		@NEW_PID INT;
     
    	SELECT @DEV_ID_SRC = DEV_ID, @DPT_PID_SRC = DPT_PID, @DPT_PID_SRC = DPT_ORD FROM dbo.T_DEVPART_DPT
    	WHERE DPT_ID = @ID_TO_COPY
     
    	SELECT @DEV_ID_DEST = DEV_ID, @DPT_PID_DEST = DPT_PID, @DPT_ORD_DEST = DPT_ORD FROM dbo.T_DEVPART_DPT
    	WHERE DPT_ID = @ID_DEST
     
    	SET @ERROR = 0;
    	SET @ROWCOUNT = 0;
    	SET @TRANCOUNT = 0;
     
    	-- démarrage transaction -------------------
    	BEGIN TRANSACTION;
    	SET @TRANCOUNT = 1;
     
    	IF @MODE = 'FA'
    	BEGIN
    		UPDATE dbo.T_DEVPART_DPT
    		SET DPT_ORD = DPT_ORD + 1
    		WHERE DPT_PID = @ID_DEST;
    		SELECT @ERROR = @@ERROR, @ROWCOUNT = @@ROWCOUNT;
    		IF @ERROR <> 0 GOTO LBL_ERROR;
     
    		SET @NEW_PID = @ID_DEST;
    		SET @NEW_ORD = 1;
    	END
    	IF @MODE = 'FC'
    	BEGIN
    		SELECT @NBE = COUNT(*) FROM dbo.T_DEVPART_DPT
    		WHERE DPT_PID = @ID_DEST;
     
    		SET @NEW_PID = @ID_DEST
    		SET @NEW_ORD = @NBE + 1
    	END
    	ELSE IF @MODE = 'GF'
    	BEGIN
    		UPDATE dbo.T_DEVPART_DPT
    		SET DPT_ORD = DPT_ORD + 1
    		WHERE DPT_PID = @DPT_PID_DEST AND DPT_ORD >= @DPT_ORD_DEST;
    		SELECT @ERROR = @@ERROR, @ROWCOUNT = @@ROWCOUNT;
    		IF @ERROR <> 0 GOTO LBL_ERROR;
     
    		SET @NEW_PID = @DPT_PID_DEST;
    		SET @NEW_ORD = @DPT_ORD_DEST;
     
    	END
    	ELSE IF @MODE = 'PF'
    	BEGIN
    		UPDATE dbo.T_DEVPART_DPT
    		SET DPT_ORD = DPT_ORD + 1
    		WHERE DPT_PID = @DPT_PID_DEST AND DPT_ORD > @DPT_ORD_DEST;
    		SELECT @ERROR = @@ERROR, @ROWCOUNT = @@ROWCOUNT;
    		IF @ERROR <> 0 GOTO LBL_ERROR;
     
    		SET @NEW_PID = @DPT_PID_DEST;
    		SET @NEW_ORD = @DPT_ORD_DEST + 1;
    	END
     
    	INSERT INTO dbo.T_DEVPART_DPT
    		(
           DEV_ID,
           DPT_PID,
           DPT_ORD,
           DPS_ID,
           DPT_FAMILLE,
           DPT_SFAMILLE,
           DPT_REF,
           DPT_LIBELLE,
           DPT_QTE,
           UPU_CODE,
           DPT_PUA1,
           DPT_MT_AJUST,
           DPT_TEXTCOM,
    	   DPT_PRN
    		)
    	SELECT
           @DEV_ID_DEST,
           @NEW_PID,
           @NEW_ORD,
           DPS_ID,
           DPT_FAMILLE,
           DPT_SFAMILLE,
           DPT_REF,
           DPT_LIBELLE,
           DPT_QTE,
           UPU_CODE,
           DPT_PUA1,
           DPT_MT_AJUST,
           DPT_TEXTCOM,
    	   DPT_PRN
    	FROM   dbo.T_DEVPART_DPT
    	WHERE DPT_ID = @ID_TO_COPY;
     
    	SET @NEW_DPT_ID = SCOPE_IDENTITY();
     
    	SELECT @ERROR = @@ERROR, @ROWCOUNT = @@ROWCOUNT;
    	IF @ERROR <> 0 OR @ROWCOUNT = 0 GOTO LBL_ERROR;
     
    	SELECT
    	@DPT_FAMILLE_DEST = DPT_FAMILLE,
    	@DPT_SFAMILLE_DEST = DPT_SFAMILLE,
    	@DPS_ID_DEST = DPS_ID
    	FROM dbo.T_DEVPART_DPT
    	WHERE DPT_ID = @NEW_DPT_ID
     
     
    	IF @DPS_ID_DEST = 4
    	BEGIN
    		SELECT @NBE = COUNT(*) FROM dbo.T_DEV_CALC_DEC
    		WHERE (DEV_ID = @DEV_ID_DEST) AND
    		(DEC_FAMILLE = @DPT_FAMILLE_DEST) AND (ISNULL(DEC_SFAMILLE, '+-*') = ISNULL(@DPT_SFAMILLE_DEST,'+-*'));
     
    		IF ISNULL(@NBE,0) = 0
    		BEGIN
    			INSERT INTO dbo.T_DEV_CALC_DEC (DEV_ID, DEC_FAMILLE, DEC_SFAMILLE)
    			VALUES (@DEV_ID_DEST , @DPT_FAMILLE_DEST, @DPT_SFAMILLE_DEST);
     
    			SELECT @ERROR = @@ERROR, @ROWCOUNT = @@ROWCOUNT;
    			IF @ERROR <> 0 OR @ROWCOUNT = 0 GOTO LBL_ERROR;
    		END
    	END;
     
    	UPDATE dbo.T_DEVIS_DEV SET DEV_ISCALC = 0
    	WHERE DEV_ID = @DEV_ID_DEST;
     
    	COMMIT TRANSACTION;
    	RETURN (0) 
     
    	LBL_ERROR:
    	IF @@TRANCOUNT > 1
    		COMMIT TRANSACTION
    	IF @TRANCOUNT > 0
    		ROLLBACK TRANSACTION
    	IF @ROWCOUNT >= 1
    		ROLLBACK TRANSACTION
    	RETURN (-1)
     
     
    END
    afin d'être en mesure de copier depuis n'importe quelle base vers la base courante sans dupliquer le code
    je pensais utiliser les synonymes mais cela semble poser un problème

    la procedure crée un synonyme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CREATE SYNONYM SourceSyn FOR [Base1].[dbo].[T_DEVPART_DPT];
    et l'utilise en table source dans la procedure

    seulement je ne voit pas comment une autre session peut faire pointer ce synonym vers par exemple base2
    sans le détruire et le recréer ce qui va forcément poser problème
    Y a t-il une autre méthode ?

  2. #2
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Par défaut
    Pas de réponses, c'est déja une information
    Je ne sais pas si je me suis bien exprimé et donné la bonne information
    en fait j'ai 5 bases de structure identiques Base 1 à 5
    Chaque base est maintenue équivalente en terme de structure aux autres
    donc pour chaque j'ai 5 procedures
    Usp_Dev_Devpart_CopyFromBase1
    Usp_Dev_Devpart_CopyFromBase2
    Usp_Dev_Devpart_CopyFromBase3
    Usp_Dev_Devpart_CopyFromBase4
    Usp_Dev_Devpart_CopyFromBase5

    a L'ajout d'une sixième je me demandais si il n'était pas possible de créer une seule procedure
    ou la base source de la copie serais donnée en paramètre et la table source BaseX.dbo.T_DEVPART_DPT
    remplacée par un synonym dans le FROM

  3. #3
    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
    Par défaut
    Bonjour,

    Quelle est la raison de cette architecture ?
    A première vue, ça semble un peu bancal, et c'est ce qui engendre votre difficulté...

    Difficile de proposer une solution. Voici néanmoins quelques pistes :

    1/ faire du SQL dynamique dans votre procédure
    2/ récupérer vos données en début de procédure dans une table temporaire, et travailler ensuite avec cette table temporaire
    3/ créer une vue regroupant toutes les tables des toutes les bases avec un discriminant et l'utiliser dans votre procédure. Si vous ne faites que des SELECT dessus, ça peut être une solution :

    La vue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    CREATE VIEW LaVue
    AS 
        SELECT 1 as NumDB, Col1, col2, col3
        FROM Base1.Schema.TableSource
        UNION ALL
        SELECT 2 as NumDB, Col1, col2, col3
        FROM Base2.Schema.TableSource
        UNION ALL
        SELECT 3 as NumDB, Col1, col2, col3
        FROM Base3.Schema.TableSource
       ...
    Puis dans votre procédure, qui prendrait le numéro de base en paramètre d'entrée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        SELECT ...
        FROM LaVue
        WHERE NumDB= @NumeroDB
        AND ...

  4. #4
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Par défaut
    En fait ces base sont sur des sites distants autonomes
    qui finissent par être rattachées au serveur central tout en gardant certaines particularités
    qui rend la fusion difficile à réaliser
    Il est vrai que je devrais gérer une seule base multi-site avec une clé par site
    Mais cela représente pas mal de boulot compte tenu de ce qui est évoqué ci-dessus

    Je vais explorer vos solutions
    La 2 et la 3 me semblent intéressantes

    Il est dommage que l'on ne puisse pas créer un synonyme vers une Base

    Merci
    Bruno Petit

  5. #5
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Par défaut
    Citation Envoyé par PickEpique Voir le message
    Il est dommage que l'on ne puisse pas créer un synonyme vers une Base
    Je veux dire un synonyme local à la procedure
    parce que évidement un synonyme vers une base ne résout pas mon problème

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 009
    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 009
    Billets dans le blog
    6
    Par défaut
    Une solution beaucoup plus astucieuse consiste à créer une procédure stockée système qui sera exécutable dans toutes les bases et dans le contexte de chacune.

    Lisez l'article que j'ai écrit à ce sujet : http://blog.developpez.com/sqlpro/p1...able_de_toutes

    Plus d'information dans mon livre : www.amazon.fr/dp/2212135920

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/02/2015, 12h00
  2. [Toutes versions] Copie entre bases différentes
    Par Gabout dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 24/06/2009, 11h58
  3. Copie d'une table entre bases, avec un champs long
    Par LaVaZza dans le forum Oracle
    Réponses: 6
    Dernier message: 18/04/2006, 17h58
  4. Transfert de table entre base de données sous delphi
    Par gregcommune dans le forum Bases de données
    Réponses: 3
    Dernier message: 27/07/2004, 08h56
  5. copie d'nue base d'un post à un autre
    Par Gential dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 21/03/2004, 20h00

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