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

Autres SGBD Discussion :

[Teradata] Variable Bteq


Sujet :

Autres SGBD

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 27
    Points : 22
    Points
    22
    Par défaut [Teradata] Variable Bteq
    Bonjour

    Je voudrais savoir s'il est possible de stocker une variable en Bteq.

    En fait mon problème est le suivant, j'ai un ensemble de scripts SQL, alimentant des tables. Dans chacun de ces fichiers, il y aussi l'alimentation d'une ou plusieurs tables de rejets (où il sera inséré les lignes rejetées par les tables cibles).

    A chaque fin de requête (dans tous les scripts), j'appelle une procédure, qui fait un compte rendu de l'insertion (nom de la table, temps d'exécution etc...)
    et cette procédure doit également insérer le nombre de lignes rejetées par la requête (ce nombre est un paramètre de la procédure)

    Donc pour toutes les autres requêtes (autres que la table de rejet), il me suffit de mettre 0 en paramètre, mais à la fin des requêtes d'insertion dans les tables de rejets, il faudrait que je puisse entrer le nombre de lignes qui ont été insérées dans la table de rejet juste avant.
    (Je ne peux pas changer la signature de la procédure, donc je dois m'en sortir avec cela)

    Donc j'aurais voulu savoir s'il existait une variable prédéfinie sous Bteq, contenant le nombre de lignes qui viennent d'être insérées,
    ou s'il était possible de stocker le contenu d'un requête dans une variable.

    exemple: var= select count(*) from TableDeRejet

    voila
    merci d'avance

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 801
    Points
    30 801
    Par défaut
    Il n'y a pas de variables en BTEQ, telles qu'on peut les rencontrer dans sqlPlus par exemple.

    En revanche, tu as à ta disposition des tables temporaires de deux types :
    GLOBAL TEMPORARY dont la structure est conservée en fin de session mais les données sont propres à la session donc invisibles des autres sessions.
    VOLATILE qui n'est connue que de la session et automatiquement supprimée à la fin de la session.

    Donc rien ne t'empêche de te créer une table temporaire de la structure qui te plaira pour y stocker tes valeurs le temps que ton traitement s'exécute.

    Par exemple :
    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
    CREATE VOLATILE TABLE myvars
        (   indice      INTEGER
        ,   valeur      BIGINT
        ,   dateheure   TIMESTAMP
        )
    ;
    /*
    --  Traitement d'alimentation
    */
    --  Mise à jour de la variable
    MERGE INTO  myvars  AS tgt
    USING   (   SELECT  1           AS idx
                    ,   COUNT(*)    AS cnt
                    ,   CURRENT_TIMESTAMP   AS dth
                FROM    tablerejet
            )   AS src
    ON  tgt.indice = src.idx
    WHEN   MATCHED THEN
        UPDATE  
            SET tgt.valeur      = src.cnt + tgt.valeur
            ,   tgt.dateheure   = src.dth 
    WHEN   NOT MATCHED THEN
        INSERT INTO tgt
            (   indice
            ,   valeur
            ,   dateheure
            )
        VALUES
            (   src.idx 
            ,   src.cnt
            ,   src.dth 
            )    
    ;
    /*
    --  Autres traitements
    */
    --  Utilisation de la valeur dans une requête
    --  S'il y a eu plus de 200 rejets je quitte en erreur
    SELECT  COUNT(*)
    FROM    myvars
    WHERE   indice = 0
        AND valeur > 200
    ;
    .IF ACTIVITYCOUNT > 0 THEN .QUIT 1
    .QUIT 0
    Dans ce cas particulier, je fais la somme des rejets rencontrés au fur et à mesure du traitement.

    Au passage, tu remarqueras l'usage de la pseudo variable ACTIVITYCOUNT qui exprime le nombre de lignes traitées par la dernière requête, mais qui ne peut être utilisée que dans un test.

    Si tu souhaites réellement utiliser des variables, pour faire des calculs complexes avec par exemple, tu peux aussi utiliser des procédures stockées. mais, à moins que cela ait changé dans les versions récentes de Teradata, leur usage n'est pas vraiment encouragé car elle ne s'exécutent que sur un seul AMP, perdant ainsi tout le bénéfice du parallélisme
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 27
    Points : 22
    Points
    22
    Par défaut
    Oui je comprends merci de ta réponse (très intéressante)

    Mais en fait, le problème est que je dois passer par une MACRO pour insérer ce nombre de lignes rejetées.

    Voici le code de cette MACRO

    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
    REPLACE MACRO DB_MACPRO.TRT_FIN
    /************************************************************************/
    /*  MACRO DE LOG INTERNE LANCEE A LA FIN DU TRAITEMENT					*/
    /************************************************************************/
     
    (
    		p_LOG_BATCH    	VARCHAR(30), -- Identification du traitement (Nom du fichier par exemple)
    		p_LOG_NB_LIGNES_REJET    	INTEGER -- Nb lignes rejetées
    )
    as
    (
       -- Mise à jour des données
    	UPDATE DB_TECH.T_LOG_TRT FROM --La table qui stocke les informations sur chaque traitement
                        (SELECT max(T_LOG_TRT1.SYB_LOG_ID) as LOG_ID
    	              FROM DB_TECH.T_LOG_TRT T_LOG_TRT1
    	              WHERE LOG_BATCH = :p_LOG_BATCH
    	              AND LOG_DAT_FIN is null
    	          ) REQ
    	SET LOG_DAT_FIN = CURRENT_TIMESTAMP(0), LOG_NB_LIGNES_REJET = :p_LOG_NB_LIGNES_REJET, 
    	SYB_LOG_DUREE_TRT = ( ( current_timestamp(0) - T_LOG_TRT.LOG_DAT_DEB )  hour(3) to second(0) ),
    	STATUT = 'OK'
       	WHERE T_LOG_TRT.LOG_ID = REQ.LOG_ID;
    );

    Donc c'est pour ça, que j'aurais aimé stocker dans une variable la valeur pour pouvoir la passer ensuite en paramètre à la MACRO.

    Mais si je pars sur ta méthode, est-ce que la table volatile créée est accessible dans la MACRO? car dans ce cas je pourrais peut-être récupérer la valeur souhaitée.

    Autre question, quand est-ce que cette table volatile est supprimée, car en fait, je vais lancer plusieurs scripts SQL (par l'intermédiaire d'un script ksh sous Unix) et donc chaque script, possède ces tables de rejets.
    Donc est-ce que je dois créer la table une fois (dans le premier script), et la réutiliser dans les autres (en la vidant à chaque fin de script donc), ou est-ce que je dois la recréer dans chaque script?

    Enfin dernière question: est-ce qu'on peut utiliser des conditions dans une macro? Car dans ce cas j'avais peut-être aussi l'idée de changer les paramètres de la MACRO et de lui passer directement le nom de la table de rejet

    Voilà merci d'avance

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 801
    Points
    30 801
    Par défaut
    Pour pouvoir compiler une macro, il est nécessaire que tous les éléments existent au moment de la compilation.
    Donc je pense que tu dois pouvoir utiliser une table GLOBAL TEMPORARY à l'intérieur d'une macro, à condition de créer la table avant de créer la macro.
    La structure d'une table GLOBAL TEMPORARY est permanente. Elle n'est pas supprimée à la fermeture de la session.
    En revanche, ses données sont associées à la session donc, dans ton cas, au script puisqu'une session ouverte au début du script est fermée implicitement à la fin. Tu peux faire tourner plusieurs scripts en parallèle qui utilisent la même table GLOBAL TEMPORARY sans en partager les données.
    Quant à passer en paramètre le nom de la table à ta macro, cela nécessite aussi de passer par du SQL dynamique pour exécuter la requête...

    Quoique... (p_nomtable est le paramètre)
    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
    MERGE INTO  myvars  AS tgt
    USING   (   SELECT  1           AS idx
                    ,   COUNT(*)    AS cnt
                FROM    tablerejet1
                WHERE   p_nomtable = 'tablerejet1'
            UNION
                SELECT  1           AS idx
                    ,   COUNT(*)    AS cnt
                FROM    tablerejet1
                WHERE   p_nomtable = 'tablerejet2'
            )   AS src
    ON  tgt.indice = src.idx
    WHEN   MATCHED THEN
        UPDATE  
            SET tgt.valeur      = src.cnt + tgt.valeur
            ,   tgt.dateheure   = CURRENT_TIMESTAMP 
    WHEN   NOT MATCHED THEN
        INSERT INTO tgt
            (   indice
            ,   valeur
            ,   dateheure
            )
        VALUES
            (   src.idx 
            ,   src.cnt
            ,   CURRENT_TIMESTAMP 
            )    
    ;
    mais il faut connaître par avance le nom des tables de rejet...

    NB : Je n'ai pas de serveur Teradata sous la main pour vérifier ce que je propose.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 27
    Points : 22
    Points
    22
    Par défaut
    Ok je pense avoir compris ta technique.
    Après toutes ces discutions j'ai 3 idées pour faire mon problème et j'aurai aimé avoir ton avis sur celle que tu penses être la meilleure (je manque un peu de recul en teradata (et même en SQL) Je ne suis que stagiaire! )

    Mais avant tout je voudrais juste ajouter une précision qui pourrait poser des problèmes.

    En fait la macro dont j'ai mis le code, est appelée après chaque requête du script. Elle permet donc de tracer le déroulement de la requête.
    Et en fait lorsque j'apelle cette macro après une insertion dans une table autre qu'un table de rejet, je dois mettre la valeur 0 pour le champ nb lignes rejetées, et le nombre de lignes de la table de rejet lorsque j'apelle la Macro après une insertion dans la table de rejet.

    Donc en fait avec la méthode que tu propose, (passer le nom de la table de rejet en paramètre), je ne sais pas si je peux obtenir 0, si je laisse ce paramètre vide pour les autres tables, a moins que pour les autres tables j'utilise une table fictive, vide, que j'appelerai pour obtenir 0 lignes.....


    Bref j'éspère que tu as suivi, en gros voici mes 3 idées:

    1) La tienne, passer le nom de la table de rejet en paramètre après une insertion dans une table de rejet (et utiliser une table fictive dans les autres cas????), à mois que l'on ne puisse utiliser des IF dans une macro ? (peux-tu me dire si on peux le faire?), et dans ce cas je pourrais utiliser un flag en paramètre pour dire si oui ou non, on calcule le nombre de lignes dans la table de rejet et sinon on insère 0)

    2) Etant donner que j'ai déjà en paramètre le nom du script, je crée une table de référence associant pour un script SQL, les tables de rejets correspondantes, et ainsi dans la Micro j'utilise cette jointure, pour récupérer les bonnes tables de rejets et compter le nombres de lignes qu'elles contiennent.

    3) (La tienne aussi d'ailleurs lol) Celle qui me paraît le plus simple à mettre en oeuvre pour moi. Je crée une table GLOBAL TEMPORARY, j'initilise sa valeur à 0. Après chaque insertion dans la table de rejet, je la met à jour, j'apelle la MACRO pour qu'elle lise la valeur, puis je la réinitialise à 0.
    Comme ça la MACRO reste générique, elle va lire la valeur dans la même table, et lors des insertions pour les tables autres que les tables de rejets, c'est bien la valeur 0 qui sera insérée.

    Voila désolé pour ce post un peu long, je souhaite juste avoir ton avis.
    Merci en tout cas.

  6. #6
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 801
    Points
    30 801
    Par défaut
    Citation Envoyé par Joelatack Voir le message
    passer le nom de la table de rejet en paramètre après une insertion dans une table de rejet (et utiliser une table fictive dans les autres cas????)
    Ou une chaine vide, ou NULL... dans tous les cas si la comparaison ne renvoie pas TRUE, le comptage n'est pas effectué.

    Citation Envoyé par Joelatack Voir le message
    à mois que l'on ne puisse uliser des IF dans une macro ?
    Je crois me souvenir que c'est possible, mais il faut vérifier dans la doc De BTEQ, que je n'ai pas sous la main.

    En fouillant un peu sur le site de Teradata, tu peux télécharger l'intégralité de la documentation.
    Il existe une version Express gratuite du SGBD, téléchargeable, complète dans ses fonctionnalités, installable sous Windows et limitée à 4 Go. Ou, si tu préfères, sous la forme d'une machine virtuelle Suse avec une limite portée à 40 Go, ce qui est confortable simplement pour s'entrainer .
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 27
    Points : 22
    Points
    22
    Par défaut
    OK

    J'ai réussi à m'en sortir, avec une table temporaire.

    J'ai pas utiliser de if (j'ai pas vu d'exemples de ce type dans la doc), mais je m'en suis sorti avec une clause Where et une UNION comme dans tes exemples précédent.

    Merci en tout cas.

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

Discussions similaires

  1. [Teradata] Appeler un script sql depuis BTEQ
    Par maserati dans le forum Autres SGBD
    Réponses: 1
    Dernier message: 03/05/2015, 11h42
  2. [Teradata] Bteq dans procedure
    Par Zobi-wane dans le forum Autres SGBD
    Réponses: 2
    Dernier message: 13/05/2008, 18h26
  3. Procédure avec un nombre variable d'arguments
    Par charly dans le forum Langage
    Réponses: 15
    Dernier message: 21/06/2002, 11h08
  4. Réponses: 4
    Dernier message: 05/06/2002, 14h35
  5. les variables globales static
    Par gRRosminet dans le forum C
    Réponses: 8
    Dernier message: 27/04/2002, 08h34

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