Fonction de substitution SQL dans Oracle 10g

9

Il y a trois ou quatre ans, j'ai lu dans un blog Oracle quelque part qu'un DBA avait utilisé pour une résolution d'incident d'urgence une fonctionnalité Oracle 10g de substitution SQL en temps réel. Fondamentalement, il a configuré Oracle de telle sorte que chaque fois qu'il recevait une certaine requête A, il exécutait une autre requête B à la place. Aucun changement de code d'application, aucun changement de schéma, juste une configuration de type "exécuter la requête B au lieu de A".

Non pas que j'envisage d'utiliser cette fonctionnalité (je peux penser à des conséquences indésirables), mais par curiosité existe-t-elle vraiment? Si oui, comment s'appelle cette fonctionnalité?

bouillon
la source
Plans
1
@Phil: Je pensais que les plans stockés n'étaient destinés qu'aux plans d'exécution. Est-il possible de les utiliser pour remplacer les requêtes réelles de la manière décrite par l'OP?
FrustratedWithFormsDesigner
1
Oui, vous pouvez modifier le texte SQL à l'aide de plans. J'ai déjà fait cela dans 9i pour modifier une requête pour ajouter quelques astuces. Cela montre comment cela se fait: pratiqueappsdba.wordpress.com/2007/05/18/… - Je ne vois pas pourquoi vous ne pouvez pas changer la requête tant que l'entrée et la sortie restent les mêmes - les contours sont évalués et remplacés au moment de l'analyse
Philᵀᴹ
1
Peut également être une vue matérialisée avec la réécriture de requête activée.
a_horse_with_no_name

Réponses:

4

Cela ressemble au package DBMS_ADVANCED_REWRITE . Tim Hall a une excellente procédure d'utilisation de ce package pour pointer les requêtes d'une application sur une table ou une vue différente .

Si vous souhaitez simplement modifier le plan de requête mais ne pas pointer la requête vers une autre table, vous pouvez utiliser des plans stockés ou des profils SQL.

Par exemple, j'ai des tables FOOavec 1 ligne et BAR2 lignes

SQL> select * from foo;

      COL1
----------
         1

SQL> select * from bar;

      COL1
----------
        66
        77

Je peux déclarer une équivalence de réécriture en disant que les requêtes contre FOOdevraient plutôt frapperBAR

begin
  sys.DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE(
    'Rewrite_Foo',
    'select col1 from foo',
    'select col1 from bar',
    false,
    'TEXT_MATCH' );
end;

Maintenant, si je mets query_rewrite_integrityà confiance, les requêtes contre FOOfinissent par frapper une table complètement différente.

SQL> alter session set query_rewrite_integrity=trusted;

Session altered.

SQL> select * from foo;

      COL1
----------
        66
        77

Cela peut créer des plans de requête plutôt intéressants où l'objet que vous interrogez est introuvable dans le plan

SQL> select * from foo;

      COL1
----------
        66
        77


Execution Plan
----------------------------------------------------------
Plan hash value: 4224476444

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |    26 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| BAR  |     2 |    26 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        584  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
Justin Cave
la source