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

Sybase Discussion :

[ASE12][TSQL]Curseur sous Sybase


Sujet :

Sybase

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 92
    Points : 65
    Points
    65
    Par défaut [ASE12][TSQL]Curseur sous Sybase
    Bonjour,

    Je dois travailler sur Sybase ASE 12 que je connais très peu.
    J'ai besoin d'utiliser un curseur mais il semble que la synthaxe soit différente du T-SQL de MS.
    Qq'un pourrait il me donner des infos svp ?
    Merci d'avance.
    jeff

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Points : 1 828
    Points
    1 828
    Par défaut
    Est-ce que c'est dans une proc stockée, ou dans un batch SQL normal?

    Si c'est dans un batch normal il faut séparer la déclaration du curseur du reste. La séquence "normale" va comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    declare CURSORNAME cursor for SELECT ... FROM ... WHERE ....
     
    open CURSORNAME
     
    fetch CURSORNAME into @var1, @var2, ...
    while @@sqlstatus = 0
    begin
        -- faire qqch avec les variables...
        fetch CURSORNAME into @var1, @var2, ...
    end
     
    close CURSORNAME
    deallocate cursor CURSORNAME
    Il y a quelques options supplémentaires qui sont bien décrites dans le manuel (p.ex. manuel de référence)

    Michael
    Michael Peppler
    Membre de TeamSybase - www.teamsybase.com

    "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 79
    Points : 78
    Points
    78
    Par défaut
    Rappel sur les curseurs :

    Variables globales relatives aux curseurs

    @@rowcount
    - Après un fetch, contient le nombre de lignes renvoyées par des fetch depuis l'ouverture de ce curseur
    - Après toute instruction DML (data manipulation langage : select, insert, update, delete), contient le nombre de lignes affectées par l'instruction
    @@sqlstatus
    - contient 0 si le dernier fetch a réussi
    - contient 1 si le dernier fetch a rencontré une erreur
    - contient 2 si le dernier fetch a échoué parce qu'il n'y a plus de ligne dans le curseur

    Fermeture d'un curseur

    ASE ferme automatiquement les curseurs quand :
    - la session qui l'a créé est terminée.
    - la procédure stockée qui l'a créé est terminée.
    On peut réouvrir un curseur fermé (close cursor_name). Le pointeur du curseur revient au commencement du resultset.
    On ne peut pas réouvrir un curseur désalloué (deallocate cursor_name) sans le recréer au préalable.

    fetch : remarques complémentaires

    fetch fait descendre toujours le pointeur jusqu'au resultset.
    Il est impossible de faire remonter le pointeur dans le resultset.
    La fermeture et la réouverture (open cursor_name & close cursor_name) fait revenir le pointeur au début.
    Par défaut, fetch retourne toujours une ligne.
    On peut utiliser l'option set cursor rows pour modifier ce positionnement.
    Syntaxe : set cursor rows NUMBER for CURSOR_NAME
    Exemple : set cursor rows 5 for CURSOR_NAME

    Recommandations

    Il faut :
    - toujours spécifier le mode du curseur dans l'instruction declare,
    - évitez de laisser les curseurs ouverts pendant une longue durée,
    - si la même opération est effectuée pour toutes les lignes d'un curseur, n'utilisez pas de curseur.

    Règles

    La table sur laquelle un curseur for update est déclaré doit :
    - avoir un index unique, ou
    - utiliser un schéma de verrouillage DataPages ou Datarows
    Les curseurs for update nécessitent un index unique sur des tables verrouillés Allpages pour permettre au curseur d'identifier chaque ligne d'une manière unique.
    Les verrouillages Datapages et Datarows des tables sont utilisés pour déterminer les ID des lignes, et un curseur for update peut les utiliser pour identifier chaque ligne.

    Exemple d'un curseur for update

    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
     
    -- Fonctionnement :
    -- Augmentez, de 50%, tous les prix inférieurs au prix moyen.
    -- Diminuez, de 25%, tous les prix supérieurs ou égaux au prix moyen.
    -- on déclare un curseur
    declare title_update cursor
    for select title_id, price from titles
    for update
    go
    -- on déclare des variables locale
    declare @avg_price money,
    @title_id int,
    @price money
    -- On ouvre le curseur
    open title_update
    -- On commence une transaction
    begin tran
    -- on calcule le prix moyen
    select @avg_price = avg(price) from titles holdlock
    -- on fait descendre le curseur tout en affectant les variables locales @title_id, @price
    fetch title_update into @title_id, @price
    -- Tant qu'il y a des lignes on boucle
    while @@sqlstatus <> 2 
       begin
          -- Gestion d'erreurs sur le curseur, si le dernier fetch a rencontré une erreur
          if @@sqlstatus = 1
             begin
                -- Annule
                rollback tran
                -- Ecriture d'un message d'erreur
                raiserror 21001 "Fetch failed in cursor"
                -- Fermeture du curseur
                close title_update
                -- Désalloue le curseur
                deallocate cursor title_update 
                -- On sort du batch
                return
             end
          -- Si le prix est inférieur à la moyenne
          if @price < @avg_price
             -- Augmente de 50%
             update titles
             set price = price * $1.50
             where current of title_update -- sur la ligne courante du curseur
          else
             -- Diminue de 25%
             update titles
             set price = price * $.75
             where current of title_update
           -- Gestion d'erreurs sur l'update ci-dessus
           if @@error <> 0
              begin
                 rollback tran
                 raiserror 22001 "Update in cursor failed"
                 close title_update
                 deallocate cursor title_update
                 return
              end
       -- On descend le pointeur
       fetch title_update into @title_id, @price
       end -- Fin du while
    -- Valide la transaction
    commit tran
    close title_update
    deallocate cursor title_update
    go -- fin du batch

  4. #4
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 47
    Points : 53
    Points
    53
    Par défaut
    bonjour je recherche une réponse à mon problème et il me semble que ce que vous avez expliqué pourrez m'y aider mais j'ai du mal à comprendre l'utilité du fetch

    dans mon cas je suis en train de créer une fonction f1 qui reçoit un paramètre Document_ID
    je dois parcourir une table Dat_document_line et lorsque l'un des champs a la même valeur que document_id, j'appel une fonction f2 en passant en paramètre une quantité et une référence

    et je somme tous les résultats obtenus dans ma fonction f1 par somme=somme+resultat F2

    donc comment est ce que je peux utiliser les fetch dans mon cas

    pour info voilà ce que fait ma fonction f2:

    ALTER FUNCTION "DBA"."fr_getProductPrice"( @Product_reference_id integer, @quantite integer)
    RETURNS numeric (28,3)
    DETERMINISTIC
    BEGIN
    DECLARE cout numeric (28,3);
    declare prix numeric(28,3);
    select Standard_price into prix
    from Ref_Product_Reference
    where Product_reference_id=@Product_reference_id;
    set cout = (@quantite*prix);
    RETURN cout;
    END

  5. #5
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 247
    Points : 473
    Points
    473
    Billets dans le blog
    1
    Par défaut
    Avec une fonction qui s'appelle fr_getProductPrice et qui retourne en fait le prix d'un produit multiplié par une quantité, ca sent l'usine à gaz cette histoire.

    Essaie donc plutot de tout faire dans une seule requete avec des agrégats et eventuellement un compute.

Discussions similaires

  1. [ASE][T-SQL]Decode sous Sybase
    Par KHOULALENE dans le forum Sybase
    Réponses: 2
    Dernier message: 09/02/2006, 11h02
  2. Réponses: 3
    Dernier message: 19/11/2004, 15h48
  3. log des requêtes sous sybase 10
    Par VsMetal dans le forum Sybase
    Réponses: 3
    Dernier message: 03/05/2004, 14h09
  4. Les index sous Sybase
    Par Emdis dans le forum Autres SGBD
    Réponses: 2
    Dernier message: 02/06/2003, 15h21
  5. Requete requête sous sybase
    Par eddie dans le forum Sybase
    Réponses: 3
    Dernier message: 02/04/2003, 14h51

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