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 :

Variables complexes dans une procédure stockée [2012]


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Novembre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 338
    Par défaut Variables complexes dans une procédure stockée
    Bonjour,
    Voilà une ligne de 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
    ALTER PROCEDURE [dbo].[ComparaisonDePeriode](@NombrePeriodeCompare as int,@PeriodeCompare as nvarchar(25),@PeriodeFin as int,@Annee as int,@ChaineFiltre as nvarchar(255),@Titre as nvarchar(50))
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
        -- Insert statements for procedure here
    	if @Periodefin-@NombrePeriodeCompare<0
    	begin
    	SELECT nom+' ('+CodeArticle+')' as Elt,datename(MONTH,dateoperation)+' '+cast(case when MONTH(dateoperation)>@PeriodeFin then @Annee-1 else @Annee end as nvarchar) as Periode,sum(QteGros+QteDetail/Rapport2) as V,@ChaineFiltre as ChaineFiltre,@Titre as Titre,case when MONTH(dateoperation)>@PeriodeFin then MONTH(dateoperation)-12 else MONTH(dateoperation) end as NbP from EntreeSortie inner join EntreeSortieArticle on EntreeSortie.NumBon=EntreeSortieArticle.NumBon and EntreeSortie.ClientFournisseur=EntreeSortieArticle.ClientFournisseur inner join p_article on EntreeSortieArticle.CodeArticle=p_article.Code where (EntreeSortie.ClientFournisseur='client') and ((month(dateoperation) between  @Periodefin-@NombrePeriodeCompare+13 and 12) and (year(dateoperation)=@annee-1)) or ((month(dateoperation) between 1 and @Periodefin) and (year(dateoperation)=@annee)) group by nom+' ('+CodeArticle+')',datename(MONTH,dateoperation)+' '+cast(case when MONTH(dateoperation)>@PeriodeFin then @Annee-1 else @Annee end as nvarchar),case when MONTH(dateoperation)>@PeriodeFin then MONTH(dateoperation)-12 else MONTH(dateoperation) end
    	end
    	else
    	begin
    	SELECT nom+' ('+CodeArticle+')' as Elt,datename(MONTH,dateoperation)+' '+cast(@Annee as nvarchar) as Periode,sum(QteGros+QteDetail/Rapport2) as V,@ChaineFiltre as ChaineFiltre,@Titre as Titre,MONTH(dateoperation) as NbP from EntreeSortie inner join EntreeSortieArticle on EntreeSortie.NumBon=EntreeSortieArticle.NumBon and EntreeSortie.ClientFournisseur=EntreeSortieArticle.ClientFournisseur inner join p_article on EntreeSortieArticle.CodeArticle=p_article.Code where (EntreeSortie.ClientFournisseur='client') and (month(dateoperation) between  @Periodefin-@NombrePeriodeCompare and  @Periodefin) and (year(dateoperation)=@annee) group by nom+' ('+CodeArticle+')',datename(MONTH,dateoperation)+' '+cast(@Annee as nvarchar),MONTH(dateoperation)
    	end
    END
    Est ce possible de créer deux variables

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @bStr1 as nvarchar(225), @bStr2 as nvarchar(225)
    @bstr1=SELECT nom+' ('+CodeArticle+')' as Elt,datename(MONTH,dateoperation)+' '+cast(case when MONTH(dateoperation)>@PeriodeFin then @Annee-1 else @Annee end as nvarchar) as Periode,sum(QteGros+QteDetail/Rapport2) as V,@ChaineFiltre as ChaineFiltre,@Titre as Titre,case when MONTH(dateoperation)>@PeriodeFin then MONTH(dateoperation)-12 else MONTH(dateoperation) end as NbP from EntreeSortie inner join EntreeSortieArticle on EntreeSortie.NumBon=EntreeSortieArticle.NumBon and EntreeSortie.ClientFournisseur=EntreeSortieArticle.ClientFournisseur inner join p_article on EntreeSortieArticle.CodeArticle=p_article.Code where (EntreeSortie.ClientFournisseur='client') and ((month(dateoperation) between  @Periodefin-@NombrePeriodeCompare+13 and 12) and (year(dateoperation)=@annee-1)) or ((month(dateoperation) between 1 and @Periodefin) and (year(dateoperation)=@annee)) group by nom+' ('+CodeArticle+')',datename(MONTH,dateoperation)+' '+cast(case when MONTH(dateoperation)>@PeriodeFin then @Annee-1 else @Annee end as nvarchar),case when MONTH(dateoperation)>@PeriodeFin then MONTH(dateoperation)-12 else MONTH(dateoperation) end
     
    @bStr2=SELECT nom+' ('+CodeArticle+')' as Elt,datename(MONTH,dateoperation)+' '+cast(@Annee as nvarchar) as Periode,sum(QteGros+QteDetail/Rapport2) as V,@ChaineFiltre as ChaineFiltre,@Titre as Titre,MONTH(dateoperation) as NbP from EntreeSortie inner join EntreeSortieArticle on EntreeSortie.NumBon=EntreeSortieArticle.NumBon and EntreeSortie.ClientFournisseur=EntreeSortieArticle.ClientFournisseur inner join p_article on EntreeSortieArticle.CodeArticle=p_article.Code where (EntreeSortie.ClientFournisseur='client') and (month(dateoperation) between  @Periodefin-@NombrePeriodeCompare and  @Periodefin) and (year(dateoperation)=@annee) group by nom+' ('+CodeArticle+')',datename(MONTH,dateoperation)+' '+cast(@Annee as nvarchar),MONTH(dateoperation)
     
    if @Periodefin-@NombrePeriodeCompare<0
    	begin
    	@bStr1
    	end
    	else
    	begin
    	@bStr2
    	end
    Je m'excuse des textes longs. Je vous prie de me montrer comment revenir à la ligne dans les balises de code

  2. #2
    Invité
    Invité(e)
    Par défaut
    Comme ça, non.
    Mais avec du TSql dynamique, c'est possible. ( un lien au hasard : https://www.mssqltips.com/sqlservert...in-sql-server/ )
    Est-ce que ça serait mieux ? À mon avis, non, car c'est plus difficile de maintenir du code entre Quote.

  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,

    Pour les retours à la ligne dans les balises code, c'est la touche entrée...

  4. #4
    Membre éclairé
    Inscrit en
    Novembre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 338
    Par défaut
    Merci 7gyY9w1ZY6ySRgPe.
    J'ai suivi les instructions et voilà où je suis arrivé

    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
    ALTER PROCEDURE [dbo].[MouvementDeCaisse] (@DateDebut as nvarchar(10),@DateFin as nvarchar(10),@Chaine as nvarchar(1000),@ChaineFiltre as 
    nvarchar(100))
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
        -- Insert statements for procedure here
    	Declare @SqlCommand as nvarchar(1000)
     
    	set @SqlCommand='select dateoperation,motif,sum(entree) as E,sum(sortie) as S,heureoperation,@ChaineFiltre as ChaineFiltre from mvt_caisse where 
    (dateoperation between @DateDebut and @DateFin)'+@Chaine+' group by dateoperation,motif,heureoperation order by dateoperation,heureoperation'
    	EXEC (@sqlCommand)
    END
    Quand j'exécute, voilà le code de l'exécution de la 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
    DECLARE	@return_value int
     
    EXEC	@return_value = [dbo].[MouvementDeCaisse]
    		@DateDebut = N'01/01/2015',
    		@DateFin = N'31/01/2015',
    		@Chaine = N'',
    		@ChaineFiltre = N'XX'
     
    SELECT	'Return Value' = @return_value
     
    GO
    et le code d'erreur suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Msg*137, Niveau*15, État*2, Ligne*1
    La variable scalaire "@ChaineFiltre" doit être déclarée.
     
    (1*ligne(s) affectée(s))
    Je voudrais comprendre ce qui n'a pas marché

  5. #5
    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
    EXEC exécute la commande dans un nouveau contexte. Dans ce contexte, @chaineFiltre n'existe pas d'où votre message.

    Vous pouvez soit
    - concaténer cette variable comme vous l'avez fait pour @chaine (mais attention, cette pratique est dangereuse car sensible aux attaques par injection
    SQL. Contrôlez bien le contenu de cette variable)
    - passer explicitement votre paramètre en utilisant sp_executesql

  6. #6
    Membre éclairé
    Inscrit en
    Novembre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 338
    Par défaut
    Je voudrais cette syntaxe avant de passer à sp_executesql.
    Voilà donc le code réamenagé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ALTER PROCEDURE [dbo].[MouvementDeCaisse] (@DateDebut as nvarchar(10),@DateFin as nvarchar(10),@Chaine as nvarchar(1000),@ChaineFiltre as nvarchar(100))
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
        -- Insert statements for procedure here
    	Declare @SqlCommand as nvarchar(1000)
     
    	set @SqlCommand='select dateoperation,motif,sum(entree) as E,sum(sortie) as S,heureoperation,'+@ChaineFiltre+' as ChaineFiltre from mvt_caisse
     where (dateoperation between '+@DateDebut+' and '+@DateFin+')'+@Chaine+' group by dateoperation,motif,heureoperation order by dateoperation,heureoperation'
    	EXEC (@sqlCommand)
    END
    Voilà le message d'erreur qu'il m'affiche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Msg*206, Niveau*16, État*2, Ligne*1
    Conflit de types d'opérandes*: date est incompatible avec int
    Msg*207, Niveau*16, État*1, Ligne*1
    Nom de colonne non valide*: 'XX'.
     
    (1*ligne(s) affectée(s))
    Je n'ai pas de valeur de type date et int. comment les deux se retrouvent dans une incompatibilité.
    par ailleurs, 'XX' est la valeur de la colonne 'ChaineFiltre'

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 30/05/2012, 13h45
  2. Variable dynamique évaluable dans une procédure stockée
    Par fifrelin70 dans le forum Développement
    Réponses: 6
    Dernier message: 25/03/2011, 11h06
  3. passage d'un nom de table dans une procédure stockée
    Par thierry V dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 26/07/2010, 16h48
  4. Tableau de variables dans une procédure stockée ?
    Par Seb33300 dans le forum Développement
    Réponses: 4
    Dernier message: 09/03/2009, 11h57
  5. Déclaration de variables dans une procédure stockée
    Par jbrasselet dans le forum Développement
    Réponses: 5
    Dernier message: 16/02/2009, 09h00

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