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 :

[T-SQL] Créer une procédure stockée à partir d'une autre procédure stockée : possible ?


Sujet :

MS SQL Server

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 107
    Points : 63
    Points
    63
    Par défaut [T-SQL] Créer une procédure stockée à partir d'une autre procédure stockée : possible ?
    Messieurs Dames,

    Je suis confronté à la problématique suivante :
    - J'ai un traitement complexe a effectuer en T-SQL.
    - J'ai donc développé plusieurs procédures stockées qui gèrent chacune une étape du traitement (genre une fonction qui fait un import de fichier et une sous-fonction qui traite une ligne de ce fichier).

    Il me faudrait créer une procédure qui :
    - Lance la création des procédures développées dans tempdb
    - Gère le pilotage de l'appel de ces procédures

    D'où ma question : est-ce possible ou est-ce que je prend tout et que je le jette ?

    Merci et bonne journée.

    G.

    Exemple un poil plus concret :

    Les procédures élémentaires :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Create Procedure ##fichierImporter(@fichierNom nvarchar(500)) As Begin (...) End
     
    Create Procedure ##elementsImporter(@BaseNom nvarchar(100), @erreurNumero nvarchar(1) = '0' output) As Begin (...) End
     
    Create Procedure ##ligneInterpreter(@BaseNom nvarchar(100), @ligneFichier nvarchar(200), As Begin (...) End
    (tout ça fonctionne en appel "manuel")

    La procédure que je souhaite mettre en place :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Create Procedure [dbo].[ps_ImportComplet](
    		@fichierNom nvarchar(500) = '...',	
    		@baseNom nvarchar(100) = '...') As
    Begin
     If OBJECT_ID('tempdb..##fichierImporter') IS not NULL
        Begin Drop Procedure ##fichierImporter End
     
     <...> Création des procédures temporaires
     
     <...> Appel des procédures temporaires
     
    End

  2. #2
    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,

    Rien ne s'oppose à ce que vous fassiez cela.
    En revanche :
    - Lance la création des procédures développées dans tempdb
    Pourquoi dans TempDB et pourquoi des procédures temporaraires ?
    Retenez que TempDB est une base de données système, probablement la plus sensible avec master, et qu'elle est utilisée par SQL Server pour bien d'autres choses

    Vous pouvez très probablement écrire du code SQL dynamique dans une base de données utilisateur

    @++

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 107
    Points : 63
    Points
    63
    Par défaut
    Merci de la réponse, M. elsuket, mais ya quand même un truc qui s'oppose à ce que je fasse ça : la syntaxe SQL... Je m'explique en reposant ma question :

    Quelle syntaxe utiliser pour créer une procédure dans une autre procédure ?

    En gros, dans mon exemple ci-dessus, par quoi dois-je remplacer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <...> Création des procédures temporaires
    pour que ça fonctionne ?

    (sans utiliser de "exec" ou de sp_executesql, parce que ya quand même plus de 500 lignes de sous procédures...)

    Merci bien et bonne journée à vous.

    P.S. : et le pourquoi de la table temporaire, bah en fait, je sais pas trop, mais ça marchait bien et ça a l'avantage de pas "polluer" ma base principale

  4. #4
    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
    (sans utiliser de "exec" ou de sp_executesql, parce que ya quand même plus de 500 lignes de sous procédures...)
    Là par contre ce n'est clairement pas possible, mais je comprend votre position.
    Vous parlez de plus de 500 procédures, ou de 500 lignes de code T-SQL ?

    P.S. : et le pourquoi de la table temporaire, bah en fait, je sais pas trop, mais ça marchait bien et ça a l'avantage de pas "polluer" ma base principale
    Certes cela fonctionne bien, mais vous allez jouer dans le bac à sable de SQL Server ...
    Si nous ne souhaitez pas polluer votre base, crééz un schéma pour cela dans votre base de données utilisateur, et en fain de traitement, collectez le nom de tous les objets qui appartiennent à ce schéma pour les supprimer

    @++

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 107
    Points : 63
    Points
    63
    Par défaut
    C'est bien 500 lignes et pas 500 sous-procédures (quand même )
    Je n'ai que 5 ou 6 sous-procédures...


    Que je suis en train de me repalucher pour en faire une seul grosse avec des curseurs partout, comme ça, ça va devenir in-mainteble.

    Arf.

    Merci de l'attention à mon souci, et bon appétit !

  6. #6
    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
    avec des curseurs partout
    Quelle horreur !
    Bannissez les curseurs, faites comme si vous ne les aviez jamais vus !

    Merci de l'attention à mon souci, et bon appétit !
    Pas de souci.
    Comme vous l'avez probablement vu, j'habite à Bangkok, donc c'est la pause de l'après-midi

    @++

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 107
    Points : 63
    Points
    63
    Par défaut
    Problème "résolu" par un contournement.

    J'ai été obligé de créer mes procédures stockées de manière non temporaire et de les appeller via une procédure principale.

    En ce qui concerne les curseurs, je veux bien que ce soit lent, mais pour des opérations complexes, je ne vois pas comment faire autrement, l'utilisation de tables temporaires étant relativement limité.

    Merci bien en tout cas de vous être penché sur le souci, M. Elsuket

  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,

    En ce qui concerne les curseurs, je veux bien que ce soit lent, mais pour des opérations complexes, je ne vois pas comment faire autrement, l'utilisation de tables temporaires étant relativement limité.
    Ni l'un ni l'autre ne sont bons.

    Postez donc votre code, ou au moins son squelette.
    Nous vous aiderons à bannir les curseurs

    @++

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 107
    Points : 63
    Points
    63
    Par défaut
    Ah bah si vous voulez m'aider, pas de souci, je suis preneur

    Voilà un petit exemple de curseur que j'utilise.
    Le contexte : je lit un fichier texte et importe son contenu dans une table temporaire.
    Je parcours ensuite les "lignes du fichiers", i.e. les colonnes de la table pour les interpréter correctement.

    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
    	If Cursor_Status('global', 'MonCurseur')  <> -3 
    	Begin
    		If Cursor_Status('global', 'MonCurseur') >= 0 
    		Begin Close MonCurseur End
    		Deallocate MonCurseur
    	End 
    	Set @Curseur = 'Declare MonCurseur cursor Global for Select * From ##tempFichierImport '
    	Exec (@Curseur)
    	---------------------------------------------
    	--Lecture de chaque ligne et qualification --
    	---------------------------------------------
    		Open MonCurseur
    			Fetch next From MonCurseur Into @ligneFichier
    			While @@Fetch_Status=0
    				Begin
    					Set @ligneTraitee = 0
    					If(LEN(@ligneFichier) > 4)
    					Begin
    						Set @EnTete = SUBSTRING(@ligneFichier,0,5)
    						If(@EnTete = 'PCRE' or @EnTete = 'PMOD')
    							Begin
    								Execute @erreurNumero = ps_ligneInterpreter_CREMOD @ligneFichier, 
    										@aCode				output,	@cDiv			output,
    										@pCode				output, @fCode			output, 
    										@sfCode				output,	@pLibelle		output, 
    										@tValeur			output,	@pRevient		output, 
    										@pVente				output,	@pType			output
    								If(@erreurNumero <> 0)
    									Begin
    										Print 'Erreur d''interprétation de la ligne ' + @ligneFichier + '( Code ' + @erreurNumero + ')'
    										Return 4
    									End
    							End
    						If(@EnTete = 'PANN')
    							Begin
    								Execute @erreurNumero = ps_ligneInterpreter_ANN @ligneFichier, @aCode output
    								If(@erreurNumero <> 0)
    									Begin
    										Print 'Erreur d''interprétation de la ligne ' + @ligneFichier + '( Code ' + @erreurNumero + ')'
    										Return 4
    									End
    							End
    						End
    					Fetch Next From MonCurseur INTO @ligneFichier
    				End
    		Close MonCurseur
    		Deallocate MonCurseur
    		Return 0
    Si vous trouvez un moyen de faire tout aussi propre (maintenable, je veux dire) et plus efficace en mémoire, bah je suis preneur

    Merci et bonne journée à vous.

  10. #10
    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
    Ah bah si vous voulez m'aider, pas de souci, je suis preneur
    Alors allons-y

    Ma première question sera de savoir quelle est la taille de votre fichier texte, parce que je ne vous recommande pas de stocker un grand nombre de lignes dans une table temporaire, puisqu'elles sont persistées dans TempDB, comme je le montre dans ce billet.

    Je pense que vous pouvez cumuler le code des deux procédures stockées dans une seule fonction UDF, et vous en servir dans une requête SELECT.
    Néanmoins pour en être certain, j'aurai besoin de savoir ce que font ces deux procédures.

    @++

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 107
    Points : 63
    Points
    63
    Par défaut
    Le fichier texte fait un gros millier de lignes avec des données sur 80 caractères par ligne maximoum

    Les deux procédures interprètent les lignes en récupérant les données (chaine de longueur fixe) en fonction de l'en-tête de chaque ligne.

    En gros, c'est comme un import de données CSV sous Excel, mais avec un format différent selon les lignes...

    Après, en fonction des données lues, ça peut correspondre à un ajout en base (avec des correspondances à faire, genre "1960" dans le fichier correspond à un enregistrement dont l'identifiant PK vaut "2"...) ou un alter en base, ou une suppression en base... Une ligne pouvant taper dans plusieurs tables... ou pas

    Comment-ça, c'est complexe ?

  12. #12
    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
    Je suis actuellement en train de travailler sur le dépouillement pour l'intégration d'un fichier texte qui me semble bien plus merdique que le votre

    Le fichier texte fait un gros millier de lignes avec des données sur 80 caractères par ligne maximoum
    Rien ne vous empêche de l'importer dans une table de base de données utilisateur.
    C'est actuellement ce que je fais

    Les deux procédures interprètent les lignes en récupérant les données (chaine de longueur fixe) en fonction de l'en-tête de chaque ligne.

    En gros, c'est comme un import de données CSV sous Excel, mais avec un format différent selon les lignes...

    Après, en fonction des données lues, ça peut correspondre à un ajout en base (avec des correspondances à faire, genre "1960" dans le fichier correspond à un enregistrement dont l'identifiant PK vaut "2"...) ou un alter en base, ou une suppression en base... Une ligne pouvant taper dans plusieurs tables... ou pas
    D'après ce paragraphe, rien ne s'oppose à un traitement sans curseurs.

    Mais là, sans un extrait du fichier et le code complet, impossible de vous aider.
    Cela dit vu la complexité de votre traitement, une procédure stockée me semble plus appropriée qu'une fonction, comme je vous l'ai proposé au départ.

    @++ ;

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 10/10/2010, 11h46
  2. Réponses: 2
    Dernier message: 05/03/2010, 14h15
  3. Réponses: 0
    Dernier message: 11/09/2009, 18h25
  4. Créer un tableau html à partir d'une requête sql
    Par biba35 dans le forum Langage
    Réponses: 5
    Dernier message: 05/02/2009, 09h14
  5. Réponses: 3
    Dernier message: 10/04/2007, 13h53

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