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 :

Requête avec curseur en sous-requête


Sujet :

MS SQL Server

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations forums :
    Inscription : Octobre 2013
    Messages : 4
    Par défaut Requête avec curseur en sous-requête
    Bonjour,

    Je débute en T-SQL et je suis bloqué sur une requête.

    J'ai la requête suivante qui me retourne la concaténation de plusieurs champs des résultats grâce à un curseur :
    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
    SET @no_facture = '66151'
     
    DECLARE C_LINES CURSOR FOR
          SELECT T1.NO_FACT, T1.INCIDENT , T1.CODE_LIGNE, T1.NO_SEQUENC, T1.REFERENCE, T1.LIBELLE
          FROM AVENTEPI as T1
          WHERE T1.NO_FACT = @no_facture
     
          union
     
          SELECT T1.NO_FACT, T1.INCIDENT , T1.CODE_LIGNE, T1.NO_SEQUENC, T1.CODE_DIVER, T1.LIBELLE
          FROM AVENTEMO as T1
          WHERE T1.NO_FACT = @no_facture
     
          union
     
          SELECT T1.NO_FACT, T1.INCIDENT , T1.CODE_LIGNE, T1.NO_SEQUENC, T1.CODE_DIVER, T1.LIBELLE
          FROM AVENTEDI as T1
          WHERE T1.NO_FACT = @no_facture
     
          ORDER BY 2, 3, 4
     
    OPEN C_LINES 
    DECLARE @no_fact INT
    DECLARE @incident CHAR(1)
    DECLARE @code_ligne INT
    DECLARE @no_sequence INT
    DECLARE @ref VARCHAR(17)
    DECLARE @libelle VARCHAR(35)
    DECLARE @concat VARCHAR(8000)
    SET @concat = ''
    FETCH C_LINES INTO @no_fact, @incident, @code_ligne, @no_sequence, @ref, @libelle
    WHILE @@FETCH_STATUS = 0
    BEGIN
          IF @no_fact IS NOT NULL
                SET @concat = @concat + @ref + ' - ' + @libelle + ' / '
          FETCH C_LINES INTO @no_fact, @incident, @code_ligne, @no_sequence, @ref, @libelle
    END
    CLOSE C_LINES
    DEALLOCATE C_LINES
    IF @concat IS NOT NULL
          SET @concat = SUBSTRING(@concat, 1, LEN(@concat) - 1)
    SELECT @concat
    Je dois maintenant récupérer les factures sur une période donnée et pour chacune d'entre elle retourner le résultat de la requête ci-dessus correspondant.

  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 : 43
    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
    Par défaut
    Bonjour,

    N'utilisez pas les curseurs : c'est lourd, lent, et contre-performant par définition. En effet SQL est par essence ensembliste : c'est à dire qu'il est conçu pour traiter les données dans leur ensemble, et pas dans leur unité.

    On peut donc réécrire votre requête comme suit :
    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
     
    SET @no_facture = '66151';
     
    WITH
    	CTE AS
    	(
    		      SELECT	NO_FACT
    				, INCIDENT
    				, CODE_LIGNE
    				, NO_SEQUENC
    				, REFERENCE
    				, LIBELLE
    		      FROM	dbo.AVENTEPI AS T1
    		      WHERE	NO_FACT = @no_facture 
    		UNION 
    		      SELECT	NO_FACT
    				, INCIDENT
    				, CODE_LIGNE
    				, NO_SEQUENC
    				, REFERENCE
    				, LIBELLE
    		      FROM	dbo.AVENTEMO AS T1
    		      WHERE	NO_FACT = @no_facture 
    		UNION 
    		      SELECT	NO_FACT
    				, INCIDENT
    				, CODE_LIGNE
    				, NO_SEQUENC
    				, REFERENCE
    				, LIBELLE
    		      FROM	dbo.AVENTEDI AS T1
    		      WHERE	NO_FACT = @no_facture 
    		ORDER BY INCIDENT, CODE_LIGNE, NO_SEQUENC
    	)
    SELECT	@concat = CASE WHEN @concat IS NULL THEN '' ELSE @concat END + @ref +  + ' - ' + REFERENCE + ' / '
    FROM	CTE
    Vous pouvez peut-être écrire UNION ALL à la place de UNION si vous êtes absolument certain que tous les lignes de chaque table sont mutuellement exclusives : cela évite le tri en vue de l'élimination automatique des lignes en doublon. Par ailleurs il est important de qualifier le nom des tables par le nom du schéma auquel elles appartiennent : par défaut c'est dbo.

    En ce qui concerne la recherche par dates, il est évident que si vous ne donnez ni le nom de la colonne date, ni la structure des tables, il nous est impossible de vous aider plus avant

    @++

Discussions similaires

  1. rapport avec condition de sous requête
    Par aigle_ma dans le forum Deski
    Réponses: 4
    Dernier message: 18/06/2007, 11h49
  2. sous requête avec liste
    Par illegalsene dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/05/2007, 12h11
  3. Requête et sous requête avec SELECT et UPDATE
    Par Véronique75ca dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 29/06/2006, 21h25
  4. [JDBC] Requête avec une date sous la forme dd/MM/yyyy
    Par sylviefrfr dans le forum JDBC
    Réponses: 6
    Dernier message: 12/11/2005, 09h35
  5. [Débutant] Requête SELECT avec max et sous-requête
    Par joefou dans le forum Langage SQL
    Réponses: 2
    Dernier message: 27/07/2005, 14h28

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