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 :

Passer un paramêtre en champs


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Inactif  
    Homme Profil pro
    Responsable BI
    Inscrit en
    Mars 2015
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Responsable BI
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mars 2015
    Messages : 62
    Par défaut Passer un paramêtre en champs
    Bonjour,

    Voilà j'ai un souci (ou besoin d'optimisation).

    J'ai une requête que j'utilise en curseur pour passer des paramètres. Le truc classique :

    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
     
    DECLARE @VerifCli VARCHAR(50)
    DECLARE @cli VARCHAR(50)
    DECLARE @nomcli VARCHAR(100)
    DECLARE @getAccountID CURSOR
    DECLARE @CodePays varchar(1)
    DECLARE @Etiquette VARCHAR(50)
    DECLARE @qte Integer
    DECLARE @cnt Integer
     
    SET @cnt = 0;
     
    SET @getAccountID = CURSOR FOR
    SELECT [Code Client Fournisseur]
          ,[Nom Client Fournisseur]
          ,[Code Article]
          ,[Quantité à Sticker]
          ,[Code Pays]
          ,[Nom Etiquette]
      FROM [etq].[Impression Standard]
      ORDER BY 1,3
     
     
    OPEN @getAccountID;
     
    FETCH FROM @getAccountID INTO @cli,@nomcli,@art,@qte,@CodePays,@Etiquette
     
    WHILE @@FETCH_STATUS = 0
        WHILE @cnt < @qte BEGIN
          EXEC [etq].[Etiquette Standard Update] @CodePays, @art, @cli, @nomcli, @Etiquette;
          SET @cnt = @cnt +1;
        END
        FETCH NEXT 
        FROM @getAccountID INTO @cli, @nomcli, @art,@qte,@CodePays,@Etiquette;
        SET @cnt = 0
    END
    END
    Ensuite, j'ai une procédure qui va pour chaque curseur trouvé, insérer une ligne dans une table

    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
    CREATE PROCEDURE [etq].[Etiquette Standard Update] @CodePays varchar(1), @art varchar(50), @cli VARCHAR(50), @nomcli VARCHAR(100), @etq VARCHAR(50) AS BEGIN
     
    DECLARE @SQL VARCHAR(8000)
     
    SET @SQL = 'INSERT INTO [etq].[Etiquette Standard] (
    	[Code Client Fournisseur],
    	[Nom Client Fournisseur],
    	[Code Article],
    	[Désignation],
    	[Code Article et Désignation],
    	[Température Minimum],
    	[Température Maximum],
    	[Poids Net],
    	[GenCode],
    	[Calorie],
    	[Calorie Joule],
    	[Matière Grasse],
    	[Matière Grasse sur Extrait Sec],
    	[Acides Gras Saturés],
    	[Glucides],
    	[Sucre],
    	[Fibres],
    	[Protéines],
    	[Sel],
    	[Description Température],
    	[Pays Origine],
    	[Dénomination Légale],
    	[Allergènes],
    	[Ingrédients],
    	[Description DLC/DLUO],
    	[Description Poids Net],
    	[Description Energie],
    	[Description Matière Grasse],
    	[Description Gras / Sec],
    	[Description Fett i. tr.],
    	[Description Acides Gras],
    	[Description Glucides],
    	[Description Sucre],
    	[Description Fibres],
    	[Description Protéines],
    	[Description Sel],
    	[Description Conserver entre],
    	[Description avant],
    	[Description et],
    	[Description conserver],
    	[Description fabrique],
    	[Description Déclaration Nutri],
    	[Description Ingrédients],
    	[Description Mg Total],
    	[Langue],
    	[Famille 1],
    	[Famille 2],
    	[Nom Etiquette])
    SELECT DISTINCT
        '+@cli+',
        '''+@nomcli+''',
        A.[SUCH],
        A.[NAME],
        A.[SUCH] + '' '' + A.NAME,
        A.[YTCSVMIN],
        A.[YTCSVMAX],
        A.[YPOIDSNET],
        A.[YGCODC1],
        REPLACE(REPLACE(A.[YKCAL], ''.'','',''),'',00000'',''''),
        A.[YKJ],
        REPLACE(A.YMGABS,''.'','',''),
        REPLACE(A.YMGSEC,''.'','',''),
        REPLACE(A.YAGS,''.'','',''),
        REPLACE(A.YGLU,''.'','',''),
        REPLACE(A.YDTSUC,''.'','',''),
        REPLACE(A.YFIB,''.'','',''),
        REPLACE(A.YPROT,''.'','',''),
        REPLACE(A.YSEL,''.'','',''),
        BE.L'+@CodePays+' +'' ''+ A.YTCSVMIN +''°C '' + BI.L'+@CodePays+' +'' ''+ A.YTCSVMAX +''°C '' + ISNULL(CO.L'+@CodePays+', '''') collate French_CI_AS,
        RE.RNAME'+@CodePays+',
        C.YKDESI'+@CodePays+',
        AL.[L'+@CodePays+'],
        I.[L'+@CodePays+'],
        DLC.[L'+@CodePays+'],
        PDS.[L'+@CodePays+'],
        EN.[L'+@CodePays+'],
        MG.[L'+@CodePays+'],
        DMG.[L'+@CodePays+'],
        FE.[L'+@CodePays+'],
        AG.[L'+@CodePays+'],
        GL.[L'+@CodePays+'],
        SU.[L'+@CodePays+'],
        FI.[L'+@CodePays+'],
        PR.[L'+@CodePays+'],
        SE.[L'+@CodePays+'],
        BE.[L'+@CodePays+'],
        CA.[L'+@CodePays+'],
        BI.[L'+@CodePays+'],
        CO.[L'+@CodePays+'],
        FA.[L'+@CodePays+'],
        DN.[L'+@CodePays+'],
        ZU.[L'+@CodePays+'],
        MP.[L'+@CodePays+'],
        '''+@CodePays+''',
        F1.[NAME3],
        F2.[NAME3],
        '''+@etq+'''
        FROM [$(AnalyzeITBI)].[dbo].Teil$Artikel A
        LEFT OUTER JOIN [$(AnalyzeITBI)].[dbo].[FC36$ComposantsArt] C
          ON C.[YART] = A.[SN] AND C.MANDKENN = 33
        LEFT OUTER JOIN [$(AnalyzeITBI)].[dbo].Regionen$RegionLandWirtschaftsraum RE
          ON RE.SN = A.urland AND RE.MANDKENN = 33
        LEFT OUTER JOIN [$(AnalyzeITBI)].[dbo].ArtBereich$Artikelbereich F1
          ON F1.SN = A.YFAM2 AND RE.MANDKENN = 33
        LEFT OUTER JOIN [$(AnalyzeITBI)].[dbo].ArtBereich$Artikelbereich F2
          ON F2.SN = A.YFAM2 AND RE.MANDKENN = 33
        LEFT OUTER JOIN [stg].[Ingredients] AL
          ON A.SN = AL.[SN Article] COLLATE FRENCH_CI_AS AND AL.[Type Ingrédient] = ''ALL''
        LEFT OUTER JOIN [stg].[Ingredients] I
          ON A.SN = I.[SN Article] COLLATE FRENCH_CI_AS AND I.[Type Ingrédient] = ''ING''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] DLC
          ON DLC.CLE = ''consoavant''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] PDS
          ON PDS.CLE = ''poidsnet''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] PO
          ON PDS.CLE = ''poidsnet''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] EN
          ON EN.CLE = ''energie''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] MG
          ON MG.CLE = ''mg''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] DMG
          ON DMG.CLE = ''grassec''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] FE
          ON FE.CLE = ''fettitr''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] AG
          ON AG.CLE = ''acidesgras''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] GL
          ON GL.CLE = ''glucides''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] SU
          ON SU.CLE = ''sucres''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] FI
          ON FI.CLE = ''fibres''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] PR
          ON PR.CLE = ''proteines''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] SE
          ON SE.CLE = ''sel''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] BE
          ON BE.CLE = ''consoentre''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] BI
          ON BI.CLE = ''et''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] CO
          ON CO.CLE = ''conserver''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] CA
          ON CA.CLE = ''consoavant''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] FA
          ON FA.CLE = ''fabrique''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] DN
          ON DN.CLE = ''declanutri''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] ZU
          ON ZU.CLE = ''ingredients''
        LEFT OUTER JOIN [etq].[Dictionnaire Fiche Article] MP
          ON MP.CLE = ''mgpoids''
    WHERE A.[SUCH] = '+@art+'
    AND A.[MANDKENN] = 33'
     
    EXEC (@SQL)
     
    RETURN 0;
     
    END
    Ce code marche nickel, mais les curseurs sont très longs.... Je pourrais lier ma table [Impression Standard] avec ma requête d'insertion mais pour ça, il faudrait que je puisse piloter pour chaque ligne les colonnes (renseigné par le pays).

    Voilà, je me demandais s'il existait un moyen avec une requête récursive ou autre de jouer, mais ça dépasse vraiment mes compétences. Vu le nombre de table, c'est difficile pour moi de faire parvenir un jeu de données, mais si vraiment y'a besoin, j'essayerai de faire qqchose.

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

    Je doute que ça fonctionne si nickel que ça. Le jour où @nomcli contiendra un guillemet simple, ça risque d'être la cata.

    De ce que j'ai compris de votre requete, c'est une mauvaise modélisation qui la rend si compliquée et vous pousse à faire du SQL Dynamique.
    Apparement, toutes vos tables contiennent N fois la même colonne, pour chaque pays ? (RE.RNAMEFR, RE.RNAMEDE,RE.RNAMEBE, RE.RNAMEEN,...) ?

    En l'état, la seule alternative serait donc de coder cela en dur en passant par un CASE pour remplacer votre exécution dynamique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CASE @CodePays
        WHEN 'FR' THEN RE.RNAMEFR
        WHEN 'DE' THEN RE.RNAMEDE
        WHEN 'EN' THEN RE.RNAMEEN
        ...
    END
    Mais le mieux serait si c'est possible de revoir la modélisation, afin d'ajouter une colonne CodePays et de rassembler toutes ces colonnes dupliquées en une seule RNAME.

    La requete serait alors plus simple à écrire et certainement bien plus performante

  3. #3
    Inactif  
    Homme Profil pro
    Responsable BI
    Inscrit en
    Mars 2015
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Responsable BI
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mars 2015
    Messages : 62
    Par défaut
    Bonjour et merci,

    Pour le guillemet simple, je l'ai géré dans la table en amont en remplaçant les quotes par du vide.
    Malheureusement effectivement, c'est bien un problème de modélisation de l'ERP qui me pousse à bricoler les choses.

    Cependant, l'idée du CASE est bonne, la requête sera beaucoup plus longue (20 cas possible de langue par champ) mais peut être plus simple et efficace.

    Je suis en train de définir le taux de charge actuel pour savoir si l'optimisation est nécessaire.

    Mon second problème venait du fait que pour la quantité (@qte) je dois dupliquer les lignes (nombre d'étiquette pour un article à imprimer). Cela contribue à rendre la procédure très longue.

  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
    Par défaut
    Pour la quantité, vous pouvez simplement créer une table utilitaire contenant les nombres de 1 à 100 (ou 1000, ou plus en fonction du besoin)

    Il reste ensuite à faire une jointure sur cette table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    INNER JOIN LaTableDeNombres T
        ON T <= @qte

  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
    Citation Envoyé par jmarkelion Voir le message
    Cependant, l'idée du CASE est bonne, la requête sera beaucoup plus longue (20 cas possible de langue par champ) mais peut être plus simple et efficace.
    Si vous ne pouvez pas modifier le modèle en amont, créez des vues qui feront le pivot (avec l'opérateur PIVOT, ou à l'ancienne avec une série d'UNION). Vous pourrez ensuite appuyer votre requete (mais aussi toutes les suivantes) sur cette vue, et tout sera plus simple (j'ai pas dit plus performant )

Discussions similaires

  1. Passer en paramètre d'un bean les champs d'un formulaires
    Par farid69 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 17/02/2013, 13h36
  2. comment passer des paramètres entre deux champs de formule ?
    Par PatricePatrice dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 13/01/2012, 08h03
  3. Réponses: 0
    Dernier message: 30/06/2011, 21h33
  4. Réponses: 2
    Dernier message: 29/06/2010, 11h04
  5. passer un nom de champs en paramètre de procédure stockée
    Par dor_boucle dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 06/02/2006, 20h10

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