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 :

Gestion d'une Table Répartie


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de zintelix3d
    Inscrit en
    Décembre 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Décembre 2007
    Messages : 171
    Par défaut Gestion d'une Table Répartie
    Bonjour et merci d'avance,

    Voila j'ai une table "Client" qui se trouve répartie (le même schéma) sur 3 postes reliés par un réseau local filaire, et j'ai deux dblink POSTE1 et POSTE2 la troisième table étant sur mon poste local

    Client, Client@POSTE1, Client@POSTE2

    Je veut réaliser les procédures SELECT, UPDATE, INSERT, DELETE de la manière la transparente possible sur les trois postes,

    Je suis très débutant en oracle, bon voila mon soucis est que il arrive dans la journée que l'un des trois postes soit indisponible pour un certain moment, et j'aimerai gérer cela sans répliquer les données pour le moment,

    Pour simplifier disant que j'ai deux tables réparties sur les trois postes:

    Client (Numclient, Numposte, Nom, Prenom); Clé primaire Numclient et Numposte
    Achat(Numachat, Numposte, Numclient, Date, Montant); Clé primaire Numachat et clé étrangère Numposte et Numclient

    Je commence par le SELECT et le INSERT:

    INSERT: insère une ligne dans la table se trouvant dans le poste local, comme exemple mon POSTE est le Numéro 3:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    create procedure NewClient(Nom in varchar,Prenom in varchar)
    as
       id integer;
    begin
        SELECT client_numclient_seq.nextval into id FROM DUAL;
        INSERT INTO CLIENT VALUES (id, 3, Nom, Prenom);
    end;
    SELECT: j'ai créer une vue CLIENTS:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CREATE VIEW CLIENTS as (SELECT * from CLIENT) UNION (SELECT * from CLIENT@POSTE1) UNION (SELECT * from CLIENT@POSTE2);
    et je met:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM CLIENTS;
    Le problème est que si l'un des postes poste 1 ou poste 2 est indisponible ou éteint j'ai:

    ERROR at line 1:
    ORA-02068: following severe error from POST1
    ORA-03113: end-of-file on communication channel
    et moi je voudrais avoir une procédure à la place par exemple,
    la liste des clients se trouvant dans mon POSTE+POSTE2
    + un message d'erreur "Attention données incomplètes! POSTE2 indisponible"

    C'est à dire avoir quand même des résultats en ignorant l'exception et la remplaçant par un message personalisé pour POSTE1 et POSTE2 ou les deux en même temps

    S'il y a quelqu'un pour m'aider à faire cela sa serait sympa, merci d'avance

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Généralement avec une base de données on est en mode client/serveur, donc 3 postes clients et 1 serveur base.
    Mais bon à mon avis le seul moyen de savoir si le poste1 est disponnible, c'est de tester la connection au serveur.
    Ne passe donc pas par une vue et insère directement les données poste par poste au sein d'une transaction par poste du style :
    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
    Create procedure p as
    --les variables à déclarer
    begin
      begin
        insert into ...
        select * from CLIENT@POSTE1;
      exception
      when others then
        --log de l'indispo du poste en question, regarde les procédures autonomous_transaction pour le log;
      end;
      begin
        insert into ...
        select * from CLIENT@POSTE2;
      exception
      when others then
        --log de l'indispo du poste en question, regarde les procédures autonomous_transaction pour le log;
      end;
      commit;
    end;
    Tu pourras alors gérer l'affichage des postes indispos en fonction de tes logs.

  3. #3
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    En fait j'ai l'impression que j'ai mal compris ton besoin.
    Tu ne veux pas rapatrier les données des autres postes sur le tien par exemple, mais tu veux pouvoir faire un SELECT sur l'ensemble des postes dispos, est ce bien ça ?
    Si c'est ça, c'est plus ou moins le même concept, tu ne peux pas utiliser une vue, il faut passer par une procéduer du style :
    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
    create procedure get_clients (cur OUT sys_refcursor) as
    v_dispo_poste1 number;
    v_dispo_poste2 number;
    begin
      begin
        select 1 into v_dispo_poste1 from dual@POSTE1;
      exception
        when others then
          v_dispo_poste1:=0;
      end;
      begin
        select 1 into v_dispo_poste2 from dual@POSTE2;
      exception
        when others then
          v_dispo_poste2:=0;
      end;
     
      if (v_dispo_poste1 =1 and v_dispo_poste2 = 0) then
        open cur for (select * from client
    		  UNION ALL 
    		  select * from client@POSTE1)
      end if;
      if (v_dispo_poste1 = 0 and v_dispo_poste2 = 1) then
        open cur for (select * from client
    		  UNION ALL 
    		  select * from client@POSTE2)
      end if;
      -- je te laisse coder la suite
    end;
    Par contre il y a un risque que le poste1 soit dispo lors du test (sur dual) et indispo lors de la requête, mais le risque est plus ou moins faible.
    Il est évidemment préférable de passer en vrai client/serveur.
    Recherche sys_refcursor sur le forum pour plus d'info sur les procédures qui renvoie des curseurs, mais je pense qu'il y a un problème de conception.

    Bon ou alors j'ai encore rien compris

  4. #4
    Membre confirmé Avatar de zintelix3d
    Inscrit en
    Décembre 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Décembre 2007
    Messages : 171
    Par défaut
    Bonjour,

    Merci pour les réponses, ehh!!!, oui j'ai pas essayez le deuxième code mais il a l'aire d'être bon, mais le problème c que j'ai dit 2 postes pour simplifier, en faite on est une 100ènes de commerciaux qui vendent des produits pharmaceutiques, cosmétiques et para-pharmaceutiques, en se déplacent avec nos portables chez nos client (chacun a ses clients) pour enregistrer sur notre base local les commandes, de nouveaux clients...

    bref en se réunis après 16h dans le nos locaux où nous somme reliés en wifi pour faire le bilan sur nos ventes, donc notre comptable et le boss ont besoin d'une vue unifié de toutes nos ventes, parfois le comptable ou le boss ont besoin de faire des modifications sur certaines commandes ou des suppressions, parfois le boss a besoin de faire un SELECT groupe by commercial pour voir les chiffre de vente quotidien (ou mensuelle ) de chaque commercial, bref, souvent y a des retardataire?!!!, et s'ils ne sont pas relié avec nous on peut pas utiliser une vue dynamique, ainsi que le nombre de POSTE peut changer (Possibilité d'ajout d'autre commerciaux),

    -Donc une architecture client/serveur (impossible), et personnes ne veut laisser la saisi des données dans le bureau, ou exporter les données sur un serveur. On envisage plus tard d'installer un serveur pour archiver les données c tous.

    -Le nombre de POSTES étant grand Pour 100 postes avec la solution des "IF" sa fait quand même 2 puissance 100 IF désolé, mais merci j'ai peut être une idée je creuse pour voir, Merci Beaucoup, Beaucoup

    Je vais voire aussi pour le UPDATE et DELETE

    UPDATE (PrimaryKey): cherche la ligne sur le poste (numposte), si trouvé modification sinon message d'erreur (ligne introuvable)

    Même chose pour delete

    A=

  5. #5
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Ok je comprends mieux l'origine des postes.
    Il est possible que le logiciel utilisé par les commerciaux propose une solution de synchronisation des données au moins vers un serveur.
    On envisage plus tard d'installer un serveur pour archiver les données c tous.
    C'est important pour du décisionnel, mais ça devrait également simplifier vos problèmes de synchro.

    Sinon pour le code tu peux utiliser du sql dynamique avec la vue USER_DB_LINK (ou ALL_DB_LINK):
    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
    CREATE procedure get_clients (cur OUT sys_refcursor) AS
    v_dispo_poste number;
    v_query varchar2(4000);
    begin
      v_query := 'select * from client ';
      for c_db_link in (select db_link from user_db_link) loop
        begin
          execute immediate 'SELECT 1 INTO v_dispo_poste FROM dual@'||c_db_link.db_link;
        exception
          when others then
    	v_dispo_poste:=0;
        end;   
        IF (v_dispo_poste = 1) then
          v_query := v_query || ' UNION ALL select * from client@'||c_db_link.db_link;
        end IF;
      end loop;
      open cur for v_query;
    end;
    Par contre ce n'est pas une solution performante ou même réellement viable.
    Je pense qu'il est plus intéressant de centraliser l'information et réfléchir sur l'alimentation du serveur plutôt que de développer ce genre de procédure difficilement maintenable.
    Mais je n'ai pas d'expérience dans le domaine de l'embarqué.

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/04/2008, 14h28
  2. Une table répartie sur plusieurs onglets
    Par cdespont dans le forum IHM
    Réponses: 8
    Dernier message: 10/08/2007, 14h20
  3. Réponses: 6
    Dernier message: 28/02/2007, 09h37
  4. [MySQL] Gestion d'une table
    Par manud59 dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 04/06/2006, 18h53
  5. Mécansime pour reproduire la gestion d'une table
    Par sinfoni dans le forum Langage
    Réponses: 6
    Dernier message: 29/03/2006, 12h25

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