2011-08-25 4 views
3

j'ai remarqué que le concept de tables temporaires dans ces deux systèmes est différent, et j'ai une rêverie .. Je le scénario suivant dans MySQL:Alternative pour une table temporaire MySQL Oracle

  1. drop table temporaire « a » si existe
  2. Créer une table temporaire « a »
  3. remplissiez avec les données par le biais d'une procédure stockée
  4. Utilisez les données dans une autre procédure stockée

Comment puis-je implémenter le même scénario dans Oracle? Puis-je (dans une procédure préférable) créer une table temporaire, la peupler et insérer des données dans une autre table (non temporaire)?

Je pense que je peux utiliser une table temporaire (globale) qui tronque sur commit, et évite les étapes 1 & 2, mais j'ai aussi besoin de l'opinion de quelqu'un d'autre.

Répondre

6

Dans Oracle, vous avez très rarement besoin d'une table temporaire en premier lieu. Vous avez généralement besoin de tables temporaires dans d'autres bases de données car ces dernières n'implémentent pas la cohérence de lecture multi-version et il est possible que quelqu'un lisant des données de la table soit bloqué pendant que votre procédure s'exécute. ne sauvegardez pas les données dans une structure séparée. Vous n'avez pas besoin de tables temporaires globales dans Oracle pour l'une de ces raisons, car les lecteurs ne bloquent pas les écrivains et les lectures incorrectes ne sont pas possibles.

Si vous avez besoin d'un emplacement temporaire pour stocker des données pendant que vous effectuez des calculs PL/SQL, les collections PL/SQL sont plus souvent utilisées que les tables temporaires dans Oracle. De cette façon, vous ne propulsez pas les données du moteur PL/SQL vers le moteur SQL et vers le moteur PL/SQL.

CREATE PROCEDURE do_some_processing 
AS 
    TYPE emp_collection_typ IS TABLE OF emp%rowtype; 
    l_emps emp_collection_type; 

    CURSOR emp_cur 
     IS SELECT * 
      FROM emp; 
BEGIN 
    OPEN emp_cur; 
    LOOP 
    FETCH emp_cur 
    BULK COLLECT INTO l_emps 
    LIMIT 100; 

    EXIT WHEN l_emps.count = 0; 

    FOR i IN 1 .. l_emps.count 
    LOOP 
     <<do some complicated processing>> 
    END LOOP; 
    END LOOP; 
END; 

Vous pouvez créer une table temporaire globale (en dehors de la procédure) et utiliser la table temporaire globale dans votre procédure comme vous utilisez une autre table. Vous pouvez donc continuer à utiliser des tables temporaires si vous le souhaitez. Mais je peux compter d'une part le nombre de fois où j'ai vraiment besoin d'une table temporaire dans Oracle.

1

Je ne vois aucun problème dans le schéma que vous utilisez.
Notez qu'il ne doit pas être une table temporaire, vous pouvez également utiliser une sorte de type de table de mémoire.

Faites ceci en créant une table comme d'habitude, puis faire

ALTER TABLE <table_name> CACHE; 

Cette priorisera la table pour le stockage en mémoire.

Tant que vous remplissez et vide la table à brève échéance, vous n'avez pas besoin de faire l'étape 1 & 2.
Rappelez-vous le modificateur cache est juste un soupçon. La table vieillit encore dans le cache et sera éventuellement perdue de mémoire.

Il suffit de faire:

  1. cache-Populate table avec des données via une procédure stockée

  2. Utilisez les données dans une autre procédure stockée, mais ne tardez pas à temps. 2a. Effacez les données dans la table de cache.

+0

Si j'utilise les données dans la deuxième procédure stockée, et ne pas attendre trop longtemps, mais la table de cache a beaucoup de données, sera-t-elle en mémoire jusqu'à ce que la procédure l'utilisant se termine? –

+0

@Moondowner, il le fera probablement, mais il pourrait pousser beaucoup d'autres données, donc cela dépend vraiment quelle approche accélère votre application plus. Vous seul pouvez le tester. – Johan

2

Vous avez raison, les tables temporaires fonctionneront.

Si vous décidez de bâton avec des tables régulières, vous pouvez utiliser les conseils @Johan a donné, ainsi que

ALTER TABLE <table name> NOLOGGING; 

pour faire de cette exécuter un peu plus vite.

1

Dans votre version MySQL, je n'ai pas vu d'étape 5 pour déposer la table a. Donc, si vous voulez ou ne voulez pas que les données du tableau persistent, vous pouvez également utiliser une vue matérialisée et simplement actualiser à la demande.Avec une vue matérialisée vous ne avez pas besoin de gérer les instructions INSERT, il suffit d'inclure le SQL:

CREATE MATERIALIZED VIEW my_mv 
NOCACHE -- NOCACHE/CACHE: Optional, cache places the table in the most recently used part of the LRU blocks 
BUILD IMMEDIATE -- BUILD DEFERRED or BUILD IMMEDIATE 
REFRESH ON DEMAND 
WITH PRIMARY KEY -- Optional: creates PK column 
AS 
SELECT * 
FROM ....; 

Ensuite, dans l'autre procédure stockée, appelez:

BEGIN 
    dbms_mview.refresh ('my_mv', 'c'); -- 'c' = Complete 
END; 

Cela dit, une table temporaire mondiale fonctionne aussi, mais vous gérez l'insertion et les exceptions.

Questions connexes