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

PL/SQL Oracle Discussion :

Condition if variable in table


Sujet :

PL/SQL Oracle

  1. #1
    Membre actif
    Inscrit en
    Juillet 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 91
    Par défaut Condition if variable in table
    Bonjour, j'aimerais connaître la meilleure façon de réaliser cette condition :

    Si la variable est dans cette table alors fais ceci ...

    En gros, ça me serait très utile d'utiliser le IN d'SQL dan un IF

    IF enregistrement in multisite then ...

    Afin que l'on teste ligne par ligne s'il existe un moment ou enregistrement=multisite en un seul coup ...


    Merci

  2. #2
    Membre émérite Avatar de Z3phur
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2007
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2007
    Messages : 680
    Par défaut
    essai de faire un curseur et de le parcourir, dans ta boucle fait ton IF, le tour est joué.

  3. #3
    Membre chevronné

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    507
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 507
    Par défaut
    Bonjour.

    Vous pouvez faire quelque chose de simple comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    BEGIN
      FOR mon_curseur IN (SELECT ligne FROM matable WHERE enregistrement IN multisite)
      LOOP
        -- je fais ce que je dois faire et je peux utiliser les valeurs de la ligne concernée
      END LOOP;
    END;

  4. #4
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Sans curseur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    declare existe number(1) ;
    begin
    select count(*) as nb into existe from emp where empno = 7499 ;
    if existe = 0 then ...
    else ...
    end if ;
    end ;

  5. #5
    Membre chevronné

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    507
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 507
    Par défaut
    fardon parle d'un test ligne à ligne, d'où le curseur.

  6. #6
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Citation Envoyé par GoLDoZ Voir le message
    fardon parle d'un test ligne à ligne, d'où le curseur.
    Mais comme il dit
    Citation Envoyé par fardon
    ou enregistrement=multisite en un seul coup
    comme je suppose qu'il veut parler de MULTISET, et commel'examen ligne à ligne est de toute façon une mauvaise idée

  7. #7
    Membre actif
    Inscrit en
    Juillet 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 91
    Par défaut
    C'est vrai que l'examun ligne à ligne n'est pas une bonne idée, je vais vous énoncé la globalité de ce que je dois faire, j'ai UNE seule erreure (une ligne qui se fusionne à une autre alors qu'elle ne devrait pas) donc peut être que vous pourrez m'aider.

    J'ai une table, ph2_item avec ses colonnes

    Order_id, customer_id, item_id, order_date,ship_date, old_sys_ref (l'ancien order_id)

    Je dois :

    - Redonner des order_id pour les insérer dans une autre table du même type.

    - Les order_id doivent être donné par ordre des order_date.

    - Certains customer (qui se trouvent identifié dans une vue que j'ai créé) ont plus d'un magasin, donc parfois il arrive qu'il y est des commandé avec la même ship_date, le même order_date, le même customer_id, et pas le même order_id, donc je dois fusionner ces lignes pour qu'elles naient plus qu'un seul order_id

    - Une fois ceci fait, on se retrouver avec un order_id (exemple 635) qui possede plusieurs fois le même item_id (1), il faut donc changer ça.


    Voilà comment j'ai procédé (mais c'est pas encore juste)

    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
    declare
     
    cursor c_ph2_item  IS SELECT * FROM ph2_item where customer_id in (select customer_id from multisite where numbersite>1) ORDER BY customer_id,order_id,item_id,ship_date for update of order_id;
    teston ph2_item.customer_id%type;
    previousline c_ph2_item%rowtype;
    max_order sales_order.order_id%type;
     
     
     
     
    begin
     
    SELECT max(order_id) INTO max_order  FROM sales_order;
     
    UPDATE ph2_item p3
    SET order_id= (SELECT orders FROM (
    SELECT dense_rank() over(ORDER BY order_date,ship_date,customer_id) orders, old_sys_ref
    FROM ph2_item )p2 WHERE p3.old_sys_ref=p2.old_sys_ref
    );
     
    update ph2_item
    set order_id= order_id+ max_order;
     
    open c_ph2_item; 
    fetch c_ph2_item into previousline;
    close c_PH2_item;
     
     
    for enreg in c_ph2_item loop
     
     if (enreg.ship_date= previousline.ship_date)
        and (enreg.customer_id= previousline.customer_id)
        and (enreg.order_date= previousline.order_date)  
        and (previousline.order_id=enreg.order_id) 
        and (previousline.old_sys_ref<>enreg.old_sys_ref) 
        and ((previousline.item_id=enreg.item_id) or (previousline.item_id>enreg.item_id)) then
     
                              update ph2_item set item_id= previousline.item_id+1
                              where current of c_ph2_item;
                              previousline.item_id:=previousline.item_id+1;
     
        else previousline.item_id:=enreg.item_id;
    end if;
                previousline.ship_date:=enreg.ship_date;
                previousline.customer_id:=enreg.customer_id;
                previousline.order_date:=enreg.order_date;
                previousline.order_id:=enreg.order_id;
                previousline.old_sys_ref:=enreg.old_sys_ref;
    end loop;
     
     
     
    end;
    En gros je fais ça en plusieur étapes :

    1- Grâce à la fonction dense_rank je trie les lignes par order_date,ship_date,customer_id, donc si des lignes ont ces 3 choses = elles obtiennent le même order_id.

    2- Ensuite je remplace ce résultat par le max de la table cible + leur rang ...

    3- J'ouvre le curseur pour ouvrir la première ligne (le curseur est fait de telle façon qu'il ne conserve que les lignes des clients multisite)

    4- Je vérifie si les lignes sont les même, auquel cas je modifie juste l'item_id.


    Voilà ... Le premier problème et la fonction dense_rank qui est assez longue à lancer (30 secondes) et qui visiblement fait 1 erreur puisque lorsque je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select count (distinct order_id) from ph2_item
    j'obtien 1850 ... au lieu de 1851 !

  8. #8
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    à quoi correspond ton 1851 ?

  9. #9
    Membre actif
    Inscrit en
    Juillet 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 91
    Par défaut
    1851 est la reponse que je dois obtenir lorsque je demande combien d order_id distinct il existe dans ma table apres les manipulations.

    C est bon, j ai reussi a le faire avec une assez longue requete mais sans utiliser dense_rank, donc au lieu de fonctionner en 30 secondes elle met 3 secondes.

    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
    -- Fusionner les lignes 
     
    declare 
     
    cursor c_multi is select * from ph2_item where customer_id in (select customer_id from multisite where numbersite>1) order by order_date, customer_id, ship_date, item_id for update of order_id;
    previous c_multi%rowtype;
    line ph2_item.order_id%type;
    itemorder ph2_item.order_id%type ;
    item ph2_item.item_id%type ;
    maximum sales_order.order_id%type;
     
    begin
     
    open c_multi;
    fetch c_multi into previous;
    close c_multi;
     
     
    for enreg in c_multi loop
     if 
            previous.ship_date=enreg.ship_date 
        and previous.order_date=enreg.order_date
        and previous.customer_id=enreg.customer_id 
        and previous.order_id<>enreg.order_id then
     
    update ph2_item 
    set order_id = previous.order_id
    where current of c_multi;
     
    previous.ship_date:=enreg.ship_date;
    previous.order_date:= enreg.order_date;
    previous.customer_id := enreg.customer_id;
     
    else previous :=enreg;
     
    end if ;
    end loop;
     
    -- Reordonner les lignes
    line:=1;
     
    for enreg in (select order_id, order_date from ph2_item  group by order_id, order_date order by order_date) loop
    update ph2_item
    set order_id= line
    where order_id=enreg.order_id;
     
    line:=line+1;
     
    end loop;
     
     
    -- Change the item id
    itemorder:=0;
    item :=0;
     
    for enreg in (select * from ph2_item order by 1) loop
    if itemorder=enreg.order_id then
     
    update ph2_item
    set item_id=item+1
    where old_sys_ref=enreg.old_sys_ref;
    item:=item+1;
     
    else
     
    update ph2_item
    set item_id=1
    where old_sys_ref=enreg.old_sys_ref;
    item:=1;
     
    end if;
    itemorder:=enreg.order_id;
     
    end loop;
     
    SELECT max(order_id) INTO maximum  FROM sales_order;
     
    update ph2_item
    set order_id= order_id+ maximum;
     
    commit;
     
     
    end ;
    /
    Vous allez surment vous noyez dans tout ce code ...

    Bref maintenant le probleme est que, leur logiciel de correction me dit que ce n est pas correct, est en dessous des indications s inscrivent, et dans les indications je n ai que des choses du genre : 'Ceci est juste' 'Ceci est correct' ...

    La suite au prochain episode

Discussions similaires

  1. [MySQL] Variable et table de données
    Par flamel dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 02/04/2008, 10h34
  2. condition + insertion dans une table
    Par masterz dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 19/10/2007, 14h30
  3. [VBA-E] Find + condition + attribution variable
    Par Helios07 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 23/03/2007, 15h33
  4. Réponses: 9
    Dernier message: 21/11/2005, 18h51
  5. UPDATE avec condition sur d'autres tables
    Par guda dans le forum Langage SQL
    Réponses: 7
    Dernier message: 10/03/2005, 11h20

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