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 :

Fonctions Pipelined et tables mutantes


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Expert Oracle
    Inscrit en
    Mai 2009
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Expert Oracle

    Informations forums :
    Inscription : Mai 2009
    Messages : 92
    Par défaut Fonctions Pipelined et tables mutantes
    Bonjour,

    Je fais des insertions en utilisant les fonctions Pipelined. J'insère à partir d'une table source T_SOURCE vers une table cible T_CIBLE, qui ont la structure suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    CREATE TABLE T_SOURCE (entite char(10), memo char(1000));
    CREATE TABLE T_CIBLE (entite char(10), seq number(4,0), memo char(1000));
    (PK de la table T_CIBLE est entite,seq)

    La commande pour insérer est la suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    BEGIN
    	INSERT  /*+ PARALLEL(t, 10) */
    	INTO    T_CIBLE t
    	SELECT  *
    	FROM    TABLE(
    				MyPackage_1.PIPE_CIBLE ( SYSDATE,
    								     CURSOR(SELECT /*+ PARALLEL(p, 10) */ * FROM T_SOURCE p)));
    EXCEPTION
    WHEN OTHERS THEN
    	/*SORTIR EN ERREUR*/
    END;
    A l'intérieur de ma fonction PIPE_CIBLE, je dois calculer moi-même la séquence qui va être insérée dans T_CIBLE (pour éviter PK), pour ça je suis obligé de faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT  NVL(MAX(seq), 0) + 1
    INTO    t_cible_record.seq
    FROM    T_CIBLE
    WHERE   entite = t_cible_record.entite;
    Mais je rencontre le problème de table mutante, vu que j'insère dans T_CIBLE et en même temps j'essaie de faire un SELECT sur la même table !!

    Je cherche donc à savoir quel est le moyen le plus performant pour calculer ma séquence sans avoir de contrainte PK.

    Merci d'avance

  2. #2
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Calculez la séquence dans le select sur la table source en utilisant par exemple un outer join avec la table cible et la fonction analytique row_number()

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454

  4. #4
    Membre confirmé
    Homme Profil pro
    Expert Oracle
    Inscrit en
    Mai 2009
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Expert Oracle

    Informations forums :
    Inscription : Mai 2009
    Messages : 92
    Par défaut
    La fonction ROW_NUMBER() ne pourra pas fonctionner dans ce cas, la table pouvant contenir des millions de lignes, alors que la séquence n'est qu'un NUMBER(4,0) !

    La solution temporaire que j'ai choisie est de créer une table intermédiaire (similaire à T_CIBLE) et faire comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE TABLE T_CIBLE_TMP (entite char(10), seq number(4,0), memo char(1000));
     
    INSERT  /*+ PARALLEL(t, 10) */
    INTO    T_CIBLE_TMP t
    SELECT  *
    FROM    TABLE(
    			MyPackage_1.PIPE_CIBLE_TMP ( SYSDATE,
                                               CURSOR(SELECT /*+ PARALLEL(p, 10) */ * FROM T_SOURCE p)));
     
     
    INSERT  /*+ PARALLEL(t, 10) */
    INTO    T_CIBLE t
    SELECT  *
    FROM    T_CIBLE_TMP;
    Dans la fonction PIPE_CIBLE_TMP je fait mon SELECT MAX FROM T_CIBLE pour récupérer la bonne séquence. Cette solution n'est sûrement pas la bonne, mais c'est ce que j'ai trouvé de mieux pour l'instant !!

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Citation Envoyé par labolabs Voir le message
    La fonction ROW_NUMBER() ne pourra pas fonctionner dans ce cas, la table pouvant contenir des millions de lignes, alors que la séquence n'est qu'un NUMBER(4,0) !
    Aucun rapport !
    Comment calculez-vous votre numéro de séquence ?

  6. #6
    Membre confirmé
    Homme Profil pro
    Expert Oracle
    Inscrit en
    Mai 2009
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Expert Oracle

    Informations forums :
    Inscription : Mai 2009
    Messages : 92
    Par défaut
    Normalement on incrémente la séquence à chaque fois que la même entité est ajoutée. Si je veux insérer 2 mémos pour la même entité 'AAA', j'aurais dans ma table:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ENTITE || SEQ || MEMO
    'AAA' || 1 || 'xxxxxxxxxxxxxxxxxxxx'
    'AAA' || 2 || 'xxxxxxxxxxxxxxxxxxxx'
    'BBB' || 1 || 'xxxxxxxxxxxxxxxxxxxx'
    'AAA' || 3 || 'xxxxxxxxxxxxxxxxxxxx'
    'BBB' || 2 || 'xxxxxxxxxxxxxxxxxxxx'
    Le max sera:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    'AAA' || 9999 || 'xxxxxxxxxxxxxxxxxxxx'
    Pouvez-vous me donner un example avec ROW_NUMBER() ?

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

Discussions similaires

  1. Fonction et returns table
    Par Mercenary Developer dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 19/10/2009, 18h27
  2. Table Mutante
    Par chiheb dans le forum Oracle
    Réponses: 5
    Dernier message: 24/04/2006, 17h22
  3. Réponses: 7
    Dernier message: 28/02/2006, 17h46
  4. update en fonction de 2 tables
    Par logisoftfr dans le forum Langage SQL
    Réponses: 2
    Dernier message: 13/01/2006, 20h33
  5. Réponses: 4
    Dernier message: 30/10/2005, 10h13

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