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, pour éviter un curseur


Sujet :

MS SQL Server

  1. #1
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut Requête, pour éviter un curseur
    Bonjour, je cherche à écrire une requête me remontant certaines données.
    Pour garder cela dans les règles de l'art j'aimerai éviter d'utiliser un curseur, et peut-être du SQL dynamique (ça semble plus compliqué...)

    Le besoin
    J'ai besoin de compter les nombres de lignes présentes dans des tables selon la valeur d'un filtre disponible dans une autre du même schéma au nom toujours identique...

    Je précise que je suis dans un contexte décisionnel, que les tables en question sont des tables de faits que je vide tous les jours et que chacun des tables de fait (ou presque) est dans un schéma différent..

    Toutes les tables de faits ont une colonne DateId et chacun des schéma à une table RefDateProcess avec une colonne DateId.

    Pour chacune des tables de fait je dois faire la jointure avec la table RefDateProcess correspondante sur cette date et compter le nombre de lignes.

    Le tout est ensuite d'insérer ces valeurs de comptage dans une table de log.

    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
     
    CREATE SCHEMA [sc1] AUTHORIZATION [dbo]
    CREATE SCHEMA [sc2] AUTHORIZATION [dbo]
    GO
     
    CREATE TABLE sc1.Ft (DateId INT, Code VARCHAR(MAX))
    CREATE TABLE sc2.Ft (DateId INT, Code VARCHAR(MAX))
    CREATE TABLE sc1.RefDateProcess (DateId INT)
    CREATE TABLE sc2.RefDateProcess (DateId INT)
    GO
     
    -- Ma liste de tables
    select 
    	sc.name, 
    	tb.name
    from 
    	sys.tables tb
    	JOIN sys.schemas sc
    		ON sc.schema_id = tb.schema_id
    where
    	tb.name like 'Ft%'
     
     
    -- Le comptage pour une table
    select COUNT(ft.DateId)
    from sc1.Ft ft
    JOIN sc1.RefDateProcess ref
    	ON ref.DateId = ft.DateId
    Le tout est alors "d'intégrer" la seconde requête dans la première

    Sachant que les tables de faits peuvent ne contenir aucune ligne bien sûr (ce que je chercher à repérer).

    Tout cela sera ensuite intégré à un report qui contiendra une date, envoyée en paramètre à une procédure qui nettoies la table de logs sur la date de la RefDateProcess puis recompte le nombre de lignes.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 883
    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 : 21 883
    Points : 53 073
    Points
    53 073
    Billets dans le blog
    6
    Par défaut
    Ceci va vous donner la requête SQL qui exécute tout :

    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
    WITH
    T0 AS
    (
    SELECT T1.TABLE_SCHEMA +'.'+ T1.TABLE_NAME AS TB1, 
           T2.TABLE_SCHEMA +'.'+ T2.TABLE_NAME AS TB2,
           ROW_NUMBER() OVER(ORDER BY T1.TABLE_SCHEMA, T1.TABLE_NAME) AS N
    FROM   INFORMATION_SCHEMA.TABLES AS T1
           INNER JOIN INFORMATION_SCHEMA.TABLES AS T2
                 ON T1.TABLE_SCHEMA = T2.TABLE_SCHEMA
                    AND T1.TABLE_NAME <> T2.TABLE_NAME
    WHERE  T1.TABLE_TYPE = 'BASE TABLE' 
      AND  T1.TABLE_NAME LIKE 'Ft%'
    ),
    T1 AS
    (
    SELECT CAST('SELECT ''' + TB1 +''', COUNT(ft.DateId) FROM ' 
           + TB1 + ' AS ft INNER JOIN '
           + TB2 + ' AS ref ON ref.DateId = ft.DateId ' 
           AS NVARCHAR(max)) AS C, N
    FROM   T0
    WHERE  N = 1
    UNION ALL
    SELECT T1.C + ' UNION ALL ' 
           + 'SELECT ''' + TB1 +''', COUNT(ft.DateId) FROM ' 
           + TB1 + ' AS ft INNER JOIN '
           + TB2 + ' AS ref ON ref.DateId = ft.DateId '
           , T0.N
    FROM   T0
           INNER JOIN T1
                 ON T1.N +1 = T0.N
    )
    SELECT TOP 1 C 
    FROM   T1
    ORDER BY N DESC
    A vous de la mettre dans une variable et de faire un EXEC (sql dynamique).

    A +

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

    Il est un peu tard ici donc la requête suivante est probablement à réécrire de façon plus élégante, mais le principe est là :

    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
    SET NOCOUNT ON
    GO
     
    DECLARE @sql nvarchar(max)
     
    DECLARE @t TABLE
    (
    	sch_name sysname
    	, table_name sysname
    	, occurences int
    )
     
    SELECT	@sql = CASE WHEN @sql IS NULL THEN '' ELSE @sql END
    		+ 'SELECT ''' + S.name + ''',''' + T.name + ''',COUNT(*) FROM ' + S.name + '.' + T.name + ' AS ft INNER JOIN ' + S.name + '.RefDateProcess AS ref ON ft.DateId = ref.DateId'
    		+ '' + CHAR(13) + CHAR(10) + 'UNION ALL' + CHAR(13) + CHAR(10)
    FROM		sys.schemas AS S
    INNER JOIN	sys.TABLES AS T ON S.schema_id = T.schema_id
    WHERE		T.name LIKE 'Ft%'
     
     
    SELECT @sql = LEFT(@sql, LEN(@sql) - 11)
     
    PRINT @sql
     
    INSERT	@t
    EXEC	sp_executeSQL @sql
     
    SELECT	sch_name
    	, table_name
    	, occurences
    FROM	@t
    @++

  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 : 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
    Points : 12 371
    Points
    12 371
    Par défaut
    Ha ben téléscopage

  5. #5
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Merci beaucoup pour ces 2 requêtes, exactement ce qu'il me fallait

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

Discussions similaires

  1. [AC-2010] Requête sur table de jonction pour éviter de recopier la même information
    Par PetitChris dans le forum Requêtes et SQL.
    Réponses: 0
    Dernier message: 26/02/2015, 08h53
  2. Fonction pour éviter une requête redondante
    Par Him dans le forum Langage
    Réponses: 2
    Dernier message: 02/03/2009, 02h36
  3. Requête paramétrée pour éviter la duplication
    Par david71 dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 29/05/2008, 12h05
  4. Aide pour éviter un curseur!
    Par bluecurve dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 18/11/2007, 15h59
  5. Formulation d'un UPDATE (pour éviter un curseur)
    Par GoLDoZ dans le forum Oracle
    Réponses: 2
    Dernier message: 15/11/2005, 16h35

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