DBMS_ADVANCED_REWRITE

connect / as sysdba
Connected.
SQL> GRANT EXECUTE ON DBMS_ADVANCED_REWRITE TO mart;
Grant succeeded.
SQL> conn mart
Enter password:
Connected.
EXEC DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE ('TEST','SELECT 1 FROM dual','SELECT 2 FROM dual',FALSE,'text_match');
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE' must
be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Please help...whats wrong in the above steps.

SQL> SELECT COUNT(*) FROM SATYA_1;
COUNT(*)
29
SQL> SELECT COUNT(*) FROM SATYA_2;
COUNT(*)
1
EXEC SYS.DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE ('TEST_QRW','SELECT COUNT(*) FROM SATYA_1','SELECT COUNT(*) FROM SATYA_2',FALSE,'text_match');
PL/SQL procedure successfully completed.
SQL> SELECT COUNT(*) FROM SATYA_1;
COUNT(*)
29
Result should : 1

Similar Messages

  • Dbms_advanced_rewrite predicates

    Is it possible to specify a predicate (aside from a join condition) in source/target sql in dbms_advanced_rewrite? None of the examples to be found appear to demonstrate this capability. I would have expected to be able to represent some sort of bind variable in the query, but this doesn't seem to be permitted. If I'm not missing something; this makes what was an exciting prospect rather useless.
    SQL> BEGIN
    2 SYS.DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE
    3 ('AT_TEST',
    4 'SELECT FULL_NAME FROM TMP_NASDAQTRADER_MPID',
    5 'SELECT FULL_NAME FROM TMP_NASDAQTRADER_MPID WHERE MPID = :BND',
    6 FALSE);
    7 END;
    8 /
    PL/SQL procedure successfully completed.
    SQL> ALTER SESSION SET query_rewrite_enabled = TRUE;
    Session altered.
    SQL> ALTER SESSION SET query_rewrite_integrity = trusted;
    Session altered.
    SQL> SELECT /*+REWRITE_OR_ERROR*/ FULL_NAME FROM TMP_NASDAQTRADER_MPID WHERE MPID = 'SUFI'; 
    SELECT /*+REWRITE_OR_ERROR*/ FULL_NAME FROM TMP_NASDAQTRADER_MPID WHERE MPID = 'SUFI'
    ERROR at line 1:
    ORA-30393: a query block in the statement did not rewrite
    SQL>

    SQL> SELECT COUNT(*) FROM SATYA_1;
    COUNT(*)
    29
    SQL> SELECT COUNT(*) FROM SATYA_2;
    COUNT(*)
    1
    EXEC SYS.DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE ('TEST_QRW','SELECT COUNT(*) FROM SATYA_1','SELECT COUNT(*) FROM SATYA_2',FALSE,'text_match');
    PL/SQL procedure successfully completed.
    SQL> SELECT COUNT(*) FROM SATYA_1;
    COUNT(*)
    29
    Result should : 1

  • 10g, DBMS_ADVANCED_REWRITE question

    Hi,
    I'm on an Oracle 10g database. I have been reading about the DBMS_ADVANCED_REWRITE package. It sounds really cool. I do have one question about how it works ...
    If I have a query ...
    select mycol1
    from mytable
    where mycol2 = 123
    order by mycol1;
    Is there any way to use this package with out knowing what '123' would be? ie it is possible it can change?
    Is it possible to do something like the following?
    select mycol1
    from mytable
    where mycol2 = VARIABLE
    order by mycol1;
    Thanks for helping this novice.

    The DBMS_ADVANCED_REWRITE package allows you to intercept specific SQL statements and replace them with alternative statements. This is done by defining functional equivalence definitions, which are used by the rewrite engine in addition to regular query rewrites. This can be useful when you need to make minor alterations to the way applications work when you don't have access to the code. This article presents a simple example of how this can be achieved
    see this link
    http://www.oracle-base.com/articles/10g/dbms_advanced_rewrite.php

  • Quesion about dbms_advanced_rewrite ???

    SCOTT@oracle10g>alter session set nls_language=american;
    Session altered.
    SCOTT@oracle10g>create table tt1 as select * from user_objects;
    Table created.
    SCOTT@oracle10g>create table tt2 as select * from dba_objects where owner='SYSTEM';
    Table created.
    SCOTT@oracle10g>exec dbms_stats.gather_table_stats(user,'TT1');
    PL/SQL procedure successfully completed.
    SCOTT@oracle10g>exec dbms_stats.gather_table_stats(user,'TT2');
    PL/SQL procedure successfully completed.
    SCOTT@oracle10g>select * from tt1 where object_id not in (select object_id from tt2);
    Execution Plan
    Plan hash value: 720405399
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |    20 |  1600 |    45   (0)| 00:00:01 |
    |*  1 |  FILTER            |      |       |       |            |          |
    |   2 |   TABLE ACCESS FULL| TT1  |    21 |  1680 |     3   (0)| 00:00:01 |
    |*  3 |   TABLE ACCESS FULL| TT2  |     1 |     5 |     4   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "TT2" "TT2" WHERE
                  LNNVL("OBJECT_ID"<>:B1)))
       3 - filter(LNNVL("OBJECT_ID"<>:B1))
    SCOTT@oracle10g>select * from tt1 where object_id not in (select object_id from tt2
      2  where object_id is not null) and object_id is not null;
    Execution Plan
    Plan hash value: 2268948225
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |     2 |   170 |     8  (13)| 00:00:01 |
    |*  1 |  HASH JOIN ANTI    |      |     2 |   170 |     8  (13)| 00:00:01 |
    |*  2 |   TABLE ACCESS FULL| TT1  |    21 |  1680 |     3   (0)| 00:00:01 |
    |*  3 |   TABLE ACCESS FULL| TT2  |   469 |  2345 |     4   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("OBJECT_ID"="OBJECT_ID")
       2 - filter("OBJECT_ID" IS NOT NULL)
       3 - filter("OBJECT_ID" IS NOT NULL)
    SCOTT@oracle10g>begin
      2    sys.dbms_advanced_rewrite.DECLARE_REWRITE_EQUIVALENCE('TEST','select * from tt1 where object_
    id not in (select object_id from tt2)','select * from tt1 where object_id not in (select object_id f
    rom tt2 where object_id is not null) and object_id is not null',false,'text_match');
      3  end;
      4  /
    PL/SQL procedure successfully completed.
    SCOTT@oracle10g>alter session set query_rewrite_integrity=trusted;
    Session altered.
    SCOTT@oracle10g>set autot trace exp
    SCOTT@oracle10g>alter session set sql_trace=true;
    Session altered.
    SCOTT@oracle10g>select * from tt1 where object_id not in (select object_id from tt2);
    Execution Plan
    Plan hash value: 2268948225
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |     2 |   170 |     8  (13)| 00:00:01 |
    |*  1 |  HASH JOIN ANTI    |      |     2 |   170 |     8  (13)| 00:00:01 |
    |*  2 |   TABLE ACCESS FULL| TT1  |    21 |  1680 |     3   (0)| 00:00:01 |
    |*  3 |   TABLE ACCESS FULL| TT2  |   469 |  2345 |     4   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("OBJECT_ID"="OBJECT_ID")
       2 - filter("OBJECT_ID" IS NOT NULL)
       3 - filter("OBJECT_ID" IS NOT NULL)
    SCOTT@oracle10g>insert into tt1(object_id) select object_id from tt2;
    469 rows created.
    SCOTT@oracle10g>exec dbms_stats.gather_table_stats(user,'TT1');
    PL/SQL procedure successfully completed.
    SCOTT@oracle10g>set autot trace exp
    SCOTT@oracle10g>select * from tt1 where object_id not in (select object_id from tt2);
    Execution Plan
    Plan hash value: 720405399
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |   489 |  7824 |   991   (1)| 00:00:12 |
    |*  1 |  FILTER            |      |       |       |            |          |
    |   2 |   TABLE ACCESS FULL| TT1  |   490 |  7840 |     3   (0)| 00:00:01 |
    |*  3 |   TABLE ACCESS FULL| TT2  |     1 |     5 |     4   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "TT2" "TT2" WHERE
                  LNNVL("OBJECT_ID"<>:B1)))
       3 - filter(LNNVL("OBJECT_ID"<>:B1))
    SCOTT@oracle10g>set autot off
    SCOTT@oracle10g>select sql_id,child_number from v$sql where sql_text='select * from tt1 where object
    _id not in (select object_id from tt2)';
    SQL_ID        CHILD_NUMBER
    dwag5726g0j91            1
    SCOTT@oracle10g>select * from table(dbms_xplan.display_cursor('dwag5726g0j91',1));
    PLAN_TABLE_OUTPUT
    SQL_ID  dwag5726g0j91, child number 1
    select * from tt1 where object_id not in (select object_id from tt2)
    Plan hash value: 720405399
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |       |       |   991 (100)|          |
    |*  1 |  FILTER            |      |       |       |            |          |
    PLAN_TABLE_OUTPUT
    |   2 |   TABLE ACCESS FULL| TT1  |   490 |  7840 |     3   (0)| 00:00:01 |
    |*  3 |   TABLE ACCESS FULL| TT2  |     1 |     5 |     4   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter( IS NULL)
       3 - filter(LNNVL("OBJECT_ID"<>:B1))
    21 rows selected.
    SCOTT@oracle10g>select * from v$version;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
    PL/SQL Release 10.2.0.3.0 - Production
    CORE    10.2.0.3.0      Production
    TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
    NLSRTL Version 10.2.0.3.0 - Productionwhen I modify tt1,query rewrite don't take effect ??

    hi sir,
    it take effects,but there are some problems.
    SCOTT@oracle10g>insert into tt1(object_id) select object_id from tt2;
    469 rows created.
    Execution Plan
    Plan hash value: 1248358058
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | INSERT STATEMENT  |      |   469 |  2345 |     4   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS FULL| TT2  |   469 |  2345 |     4   (0)| 00:00:01 |
    SCOTT@oracle10g>select * from tt1 where object_id not in (select object_id from tt2); 
    Execution Plan
    Plan hash value: 720405399
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |   506 |  9614 |  1026   (1)| 00:00:13 |
    |*  1 |  FILTER            |      |       |       |            |          |
    |   2 |   TABLE ACCESS FULL| TT1  |   507 |  9633 |     3   (0)| 00:00:01 |
    |*  3 |   TABLE ACCESS FULL| TT2  |     1 |     5 |     4   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "TT2" "TT2" WHERE
                  LNNVL("OBJECT_ID"<>:B1)))
       3 - filter(LNNVL("OBJECT_ID"<>:B1))
    SCOTT@oracle10g>commit;
    Commit complete.
    SCOTT@oracle10g>select * from tt1 where object_id not in (select object_id from tt2);
    Execution Plan
    Plan hash value: 2314021845
    | Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT     |      |    38 |   912 |     8  (13)| 00:00:01 |
    |*  1 |  HASH JOIN RIGHT ANTI|      |    38 |   912 |     8  (13)| 00:00:01 |
    |*  2 |   TABLE ACCESS FULL  | TT2  |   469 |  2345 |     4   (0)| 00:00:01 |
    |*  3 |   TABLE ACCESS FULL  | TT1  |   507 |  9633 |     3   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("OBJECT_ID"="OBJECT_ID")
       2 - filter("OBJECT_ID" IS NOT NULL)
       3 - filter("OBJECT_ID" IS NOT NULL)
       when I declare a new rewrite,enq: RW - MV metadata contention happens,and the blocking_session and blocked session are same session .
    SYS@oracle10g>col event for a50
    SYS@oracle10g>set linesize 300
    SYS@oracle10g>select sid,serial#,event,blocking_session from v$session where username='SCOTT';
           SID    SERIAL# EVENT                                              BLOCKING_SESSION
           157          7 enq: RW - MV metadata contention                                157

  • DBMS_ADVANCED_REWRITE license?

    Howdy,
    Hopefully this is a quick question, do I need the oracle tuning license to use the DBMS_ADVANCED_REWRITE package? I currently only have the oracle standard edition license.
    Background for the curious: Started doing an overall design analysis of a several year old application that has been in continuous development. As a result, I found that one particular where clause condition is taking a disproportionately long time to execute and that this particular condition is in over 80 different places in the code. Team is unlikely to get the budget to go ahead and clean-out all locations so, I'm hoping I can offer the rewrite package as a bandaid.
    Format of the problematic where condition:
    WHERE table_a.table_a_id in (SELECT table_a_id FROM table_b WHERE table_b_id IN (SELECT table_b_id FROM ...<snip>... WHERE table_i.version=:version))))))))))

    Ask your Oracle sales rep. We, as non-employee volunteers, cannot speak to Oracle licensing and legal issues in most cases.

  • Dbms_advanced_rewrite to return a new date

    Is there a way to offset the database date by a given amount of months/days/years so that when the sysdate is queried, it returns a date which equals the current date+the offset? This has to be done without changing the server's OS date.
    I'm trying to achieve it using 'dbms_advanced_rewrite' but getting the following error.
    begin
    sys.dbms_advanced_rewrite.declare_rewrite_equivalence (
    'new_query',
    'select sysdate as tdt from dual',
    'select sysdate+180 as tdt from dual',
    false);
    end;
    2 3 4 5 6 7 8 begin
    ERROR at line 1:
    ORA-30353: expression not supported for query rewrite
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 29
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 185
    ORA-06512: at line 2
    any help would be much appreciated.
    thanks

    I don't know why the error is occurring. I've worked with DBMS_ADVANCED_QUERY_REWRITE a little, enough to find out that you can alter result sets using it. My exercise was to get a 'Y' instead of an 'X' from DUAL, and the exercise was successful. I didn't try using SYSDATE with it.
    What happens if you use ROWNUM (another pseudocolumn) instead of SYSDATE? What happens if you use a literal or database column value?
    Can you approach the problem from a different way? Specifically, could you create a view with the query you want and then alter the value in the view as needed, having your user use the view instead of a straight query. Not as elegant, but it should work

  • TOP-N query optimization

    Hi,
    We have a 3rd party GUI component which provides data paging capabilities by using the "ROW_NUMBER" analytic function. Sadly it does that in an inefficient way, because it forces Oracle to perform a large sort only to later discard a large portion of data. By slightly modifying the query, it is possible to fix that (demonstrated below), but the problem is that I can't change the SQL the component issues.
    I'd appreciate if anyone has any suggestion whether it's possible to fix that in some way.
    Test case:
    SQL> create table test (
      2     id           number (10) not null,
      3     c1           number (2) not null,
      4     other_data   varchar2 (200)
      5  );
    Table created.
    SQL> insert into test
      2  with generator as (
      3      select  --+ materialize
      4         rownum id
      5      from dual
      6      connect by
      7          rownum <= 10000
      8  )
      9  select
    10      rownum     id,
    11      mod(rownum, 20),
    12      rpad('x',200)
    13  from
    14      generator   v1,
    15      generator   v2
    16  where   rownum <= 1000000
    17  ;
    1000000 rows created.
    SQL> commit;
    Commit complete.
    SQL> create index i_1 on test(id, c1);
    Index created.
    SQL> exec dbms_stats.gather_table_stats(user,'TEST',cascade=>true);
    PL/SQL procedure successfully completed.This is the SQL the 3rd party component issues:
    SQL> SELECT *
      2    FROM (  SELECT t2.*, ROW_NUMBER () OVER (ORDER BY t2.id) AS "rnum"
      3              FROM (SELECT *
      4                      FROM test
      5                     WHERE c1 != 5) t2
      6          ORDER BY t2.id) t1
      7   WHERE t1."rnum" <= 10;Here you can see that in line 3 of the execution plan, the whole table is read and in line 2 it's sorted to find the required 10 rows:
    | Id  | Operation                | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
    |   0 | SELECT STATEMENT         |      |      1 |        |     10 |00:00:00.93 |   30502 |  30497 |    |          |          |
    |*  1 |  VIEW                    |      |      1 |    950K|     10 |00:00:00.93 |   30502 |  30497 |    |          |          |
    |*  2 |   WINDOW SORT PUSHED RANK|      |      1 |    950K|     11 |00:00:00.93 |   30502 |  30497 |  4096 |  4096 | 4096  (0)|
    |*  3 |    TABLE ACCESS FULL     | TEST |      1 |    950K|    950K|00:00:00.49 |   30502 |  30497 |    |          |          |
    Predicate Information (identified by operation id):
       1 - filter("T1"."rnum"<=10)
       2 - filter(ROW_NUMBER() OVER ( ORDER BY "TEST"."ID")<=10)
       3 - filter("C1"<>5)However, by moving the "ORDER BY" to the outermost part of the query, Oracle can use the index I_1 to read only 10 rows from it and stop as soon as it reaches that count. And what's more important, no sorting takes place:
    SQL>   SELECT *
      2      FROM (SELECT t2.*, ROW_NUMBER () OVER (ORDER BY t2.id) AS "rnum"
      3              FROM (SELECT *
      4                      FROM test
      5                     WHERE c1 != 5) t2
      6           )
      7     WHERE "rnum" <= 10
      8  ORDER BY id;
    | Id  | Operation                     | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
    |   0 | SELECT STATEMENT              |      |      1 |        |     10 |00:00:00.01 |       6 |      2 |       |       |          |
    |*  1 |  VIEW                         |      |      1 |    950K|     10 |00:00:00.01 |       6 |      2 |       |       |          |
    |*  2 |   WINDOW NOSORT STOPKEY       |      |      1 |    950K|     10 |00:00:00.01 |       6 |      2 |   213M|  4884K|          |
    |   3 |    TABLE ACCESS BY INDEX ROWID| TEST |      1 |    950K|     11 |00:00:00.01 |       6 |      2 |       |       |          |
    |*  4 |     INDEX FULL SCAN           | I_1  |      1 |    950K|     11 |00:00:00.01 |       4 |      1 |       |       |          |
    Predicate Information (identified by operation id):
       1 - filter("rnum"<=10)
       2 - filter(ROW_NUMBER() OVER ( ORDER BY "TEST"."ID")<=10)
       4 - filter("C1"<>5)Is there any way to "fix" the first query without changing it (maybe using an outline, but I don't see how Oracle can avoid the whole table sort)?
    Thanks in advance and regards,
    Jure

    Thank you very much for the link to DBMS_ADVANCED_REWRITE. I didn't know of its existence and it sure seems a useful tool for situations similar to mine (I'm on 11.2.0.1).
    However, I encountered two problems when trying to rewrite my query. Maybe I did something obviously wrong, since that's the first time I use DBMS_ADVANCED_REWRITE:
    1) The rewrite doesn't seem to work if the source statement contains an ORDER BY clause, which is an essential part of the query I'm trying to rewrite. I reproduced it here such that if the rewrite takes place, I get back the "rewritten query" text (plus some dummy columns to match the resultset structure of the original query), otherwise 10 rows are returned.
    First I setup the rewrite equivalence:
    SQL> begin
      2    sys.dbms_advanced_rewrite.declare_rewrite_equivalence (
      3      name             => 'DEMO',
      4      source_stmt      =>
      5      'SELECT *
      6         FROM (  SELECT t2.*, ROW_NUMBER () OVER (ORDER BY t2.id) AS "rnum"
      7                   FROM (SELECT *
      8                           FROM test
      9                          WHERE c1 != 5) t2
    10               ORDER BY t2.id) t1
    11        WHERE t1."rnum" <= 10',
    12      destination_stmt => 'select null dummy_a, null dummy_b, ''rewritten query'' dummy_c, 1 dummy_rownum from dual',
    13      validate         => FALSE,
    14      rewrite_mode     => 'GENERAL'
    15    );
    16  end;
    17  /
    PL/SQL procedure successfully completed.Now I try to run the query with the exact same query text as defined in "source_stmt". No rewrite takes place:
    SQL> SELECT *
      2    FROM (  SELECT t2.*, ROW_NUMBER () OVER (ORDER BY t2.id) AS "rnum"
      3              FROM (SELECT *
      4                      FROM test
      5                     WHERE c1 != 5) t2
      6          ORDER BY t2.id) t1
      7   WHERE t1."rnum" <= 10
      8  /
    <10 rows are retireved>However, if I remove the "ORDER BY t2.id" part from the "t1" query block, the rewrite works:
    SQL> exec sys.dbms_advanced_rewrite.drop_rewrite_equivalence('DEMO');
    PL/SQL procedure successfully completed.
    SQL> begin
      2    sys.dbms_advanced_rewrite.declare_rewrite_equivalence (
      3      name             => 'DEMO',
      4      source_stmt      =>
      5      'SELECT *
      6         FROM (  SELECT t2.*, ROW_NUMBER () OVER (ORDER BY t2.id) AS "rnum"
      7                   FROM (SELECT *
      8                           FROM test
      9                          WHERE c1 != 5) t2
    10               ) t1
    11        WHERE t1."rnum" <= 10',
    12      destination_stmt => 'select null dummy_a, null dummy_b, ''rewritten query'' dummy_c, 1 dummy_rownum from dual',
    13      validate         => FALSE,
    14      rewrite_mode     => 'GENERAL'
    15    );
    16  end;
    17  /
    PL/SQL procedure successfully completed.
    SQL> SELECT *
      2    FROM (  SELECT t2.*, ROW_NUMBER () OVER (ORDER BY t2.id) AS "rnum"
      3              FROM (SELECT *
      4                      FROM test
      5                     WHERE c1 != 5) t2
      6          ) t1
      7   WHERE t1."rnum" <= 10
      8  /
    I C OTHER_DATA            rnum
        rewritten query          1But the problem is of course that the rewrite should take place also when the "ORDER BY" part is provided in the query, since this is what the application issues:
    SQL> SELECT *
      2    FROM (  SELECT t2.*, ROW_NUMBER () OVER (ORDER BY t2.id) AS "rnum"
      3              FROM (SELECT *
      4                      FROM test
      5                     WHERE c1 != 5) t2
      6          ORDER BY t2.id) t1
      7   WHERE t1."rnum" <= 10
      8  /
    <10 rows are retrieved, so no rewrite took place>Maybe the reason for such a behaviour (I don't know how to prove it) is that materialized views don't store the ORDER BY clause as part of their definition, and the same rewrite engine that is used for materialized views is used for equivalence query rewrite:
    http://download.oracle.com/docs/cd/E11882_01/appdev.112/e16760/d_advrwr.htm#sthref154
    Query rewrite using equivalence declarations occurs simultaneously and in concert with query rewrite using materialized views. The same query rewrite engine is used for both.
    http://download.oracle.com/docs/cd/E11882_01/server.112/e16579/basicmv.htm#DWHSG8208
    The ORDER BY clause is not considered part of the materialized view definition
    Maybe I'm completely wrong, so any suggestion is welcome.
    2) I didn't mention that "WHERE "rnum" <= 10" is actually "WHERE "rnum" <= :b", and bind variables aren't supported for rewrite. I checked the MOS document "Using DBMS_ADVANCED_REWRITE When Binds Are Present (Avoiding ORA-30353) [ID 392214.1]" and maybe I could remove the WHERE clause, but I'd have to further test which "similar" queries would be rewritten to this one, since REWRITE_MODE is 'GENERAL' instead of 'TEXT_MATCH'. But I'd first have to resolve problem number 1) above :-)
    Thanks in advance for any answers.
    Regards,
    Jure

  • How come there is no trigger on select in Oracle

    I'm encrypting a value on insert into the table:
    insert into table1 (name, ssn) values ('John Smith','123-45-6789');
    ssn value gets encrypted and stored either in ssn_enc column or in a separate table on insert trigger.
    But now I want to use:
    select name, ssn from table1;
    And get the decrypted value out. So that's where a select trigger would fit nicely.
    Do I really need to complicate it with an overlaying view?
    P.S. I have to use this type of encryption, because Oracle Streams do not support TDE in Oracle 10g, and we are replicating encrypted data.

    @wateenmooiedag: Sorry didn't see you also mentioned DBMS_ADVANCED_REWRITE. ;)
    I made a small testcase to show that DBMS_ADVANCED_REWRITE indeed works as expected:
    SQL>  create table table1 (name, ssn) as select 'John Smith' name, to_char(to_clob(dbms_crypto.encrypt(utl_raw.cast_to_raw ('123-45-6789'),1 + 256 + 4096,utl_raw.cast_to_raw('michaels')))) ssn from dual
    Table created.
    SQL>  select name, ssn from table1
    NAME                           SSN                                    
    John Smith                     F9B1AEECF8B836BFB4C4B555C3922EE9       
    1 row selected.
    SQL>  begin
       sys.dbms_advanced_rewrite.declare_rewrite_equivalence
          ('sal_rewrite',
           'select name, ssn from table1',
           'select name, utl_raw.cast_to_varchar2(dbms_crypto.decrypt (ssn, 1 + 256 + 4096, utl_raw.cast_to_raw (''michaels''))) ssn from table1',
           false,
           'general'
    end;
    PL/SQL procedure successfully completed.
    SQL>  alter session set query_rewrite_integrity = trusted
    Session altered.
    SQL>  select name, ssn from table1
    NAME                           SSN                                    
    John Smith                     123-45-6789                            
    1 row selected.

  • SQL Query rewrite, remove ORDER BY clause

    Hello,
    we've just installed a proprietary application which uses an Oracle 11.2.0.2 RAC database. We've seen that one of the auto-generated application's queries
    has poor performance (3-5 minutes for results), the query does a SELECT and at the end it uses an ORDER BY clause. If we remove the ORDER BY clause
    the query returns the results in less than 5 seconds. Unfortunately, we can't re-write the query in the application since we don't have any access to it and
    i was wondering if there is a way to rewrite the specific query from the database.
    We've already seen the SQL Patch but we can change only the hints of the query so we can't remove the ORDER BY clause from it. From what we've seen
    outlines also change only the hints and not the actual sql statement.
    Is there a way to rewrite the specific query from the database ?
    thanks in advance,
    Giannis

    Maybe DBMS_ADVANCED_REWRITE can help but this a SQL question than has very likely nothing to do with RAC.
    See http://www.oracle-base.com/articles/10g/dbms_advanced_rewrite.php.

  • Replace a sql_id with another

    Hi,
    i'm in 11.2 on Linux.
    I've an application that perform some queries with many function.
    For ex:
    select funct(field1,0),
    funct(field2,' '),
    funct(field3,' '),
    funct(field4,0),
    funct(field5,0)
    from ....
    This function is a custom NVL and the performance is poor.
    I cannot change the application and i want to know if i can use, for ex, stored outline to remap this sql_id to another using nvl function.
    Thank you.

    maybe you could use dbms_advanced_rewrite to map your query to another query: http://dioncho.wordpress.com/2009/03/06/optimizing-unoptimizeable-sql-dbms_advanced_rewrite/. But of course this could lead to grieve and sorrow - if the information of the use of this "workaround" is not given to all the people involved...

  • Hide an error from the application using a servererror trigger?

    We have an application designed for an old oracle version which issues some sql which is no more supported in todays database version.
    We want to use the application unchanged with a new database server.
    Old Server Version: 7.3.4 (still in production...)
    New Server Version: 10.2 or 11.2
    The application issues an
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS ;
    which results in ORA-01986 and the application dies.
    We would like to hide the error 01986 from the application using a trigger:
    create or replace
    trigger catch01986
      after servererror
      on schema
      begin
        if (ora_is_servererror (1986)) then
          null; -- what to do here? we want clear the ora-01986 from the error stack
        end if;
      end catch01986;How to handle the error, so that the alter session set ... statement is just ignored and no error code is returned to the application?
    I asked already some days ago in Database-General Forum, but triggers belong to PL/SQL, so i repost here.
    Tnx for help in advance!

    Hi,
    hoek wrote:
    A totally weird and untested (and unable to test today) thought:
    http://technology.amis.nl/blog/447/how-to-drive-your-colleagues-nuts-dbms_advanced_rewrite-oracle-10g
    Very interesting for real dirty solution.
    Does not work for my problem, DBMS_ADVANCED_REWRITE works only for select statements.
    BEGIN
       SYS.DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE (
       'alter_session_equivalence',
       'ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS',
       'ALTER SESSION SET OPTIMIZER_MODE = RULE',
       FALSE);
    END;
    ORA-30389: the source statement is not compatible with the destination statement
    ORA-00903: invalid table name
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 29
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 185
    ORA-06512: at line 2
    30389. 00000 -  "the source statement is not compatible with the destination statement"
    *Cause:    The SELECT clause of the source statement is not compatible with
               the SELECT clause of the destination statement
    *Action:   Verify both SELECT clauses are compatible with each other such as
               numbers of SELECT list items are the same and the datatype for
               each SELECT list item is compatible
    hoek wrote:You already had some trigger code, catching the error and sending it to null, why didn't that work?The trigger is fired when the error occurs, but after completion of the trigger, the error code is still delivered to the client.
    I dont know how to handle the error within the trigger.
    Does the client read the error stack and does it die after reading an error from the stack?The client just checks the error code. On error it terminates.
    With the SERVERERROR TRIGGER i did the following tests:
    Test 1: trigger does nothing
    CREATE OR REPLACE
    TRIGGER CATCH01986
      AFTER SERVERERROR
      ON SCHEMA
      BEGIN
        IF (ORA_IS_SERVERERROR (1986)) THEN
          NULL;
        END IF;
      END CATCH01986;
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS;
    ORA-01986: OPTIMIZER_GOAL is obsolete
    01986. 00000 -  "OPTIMIZER_GOAL is obsolete"
    *Cause:    An obsolete parameter, OPTIMIZER_GOAL, was referenced.
    *Action:   Use the OPTIMIZER_MODE parameter.
    -- Client Application reports errorcode 1986Test 2: Trigger raises NO_DATA_FOUND
    CREATE OR REPLACE
    TRIGGER CATCH01986
      AFTER SERVERERROR
      ON SCHEMA
      BEGIN
        IF (ORA_IS_SERVERERROR (1986)) THEN
          RAISE NO_DATA_FOUND;
        END IF;
      END CATCH01986;
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS;
    ORA-04088: error during execution of trigger 'AH.CATCH01986'
    ORA-01403: no data found
    ORA-06512: at line 9
    ORA-01986: OPTIMIZER_GOAL is obsolete
    04088. 00000 -  "error during execution of trigger '%s.%s'"
    *Cause:    A runtime error occurred during execution of a trigger.
    *Action:   Check the triggers which were involved in the operation.
    -- Client Application reports errorcode 4088Test 3: Trigger raising an APPLICATION ERROR
    CREATE OR REPLACE
    TRIGGER CATCH01986
      AFTER SERVERERROR
      ON SCHEMA
      BEGIN
        IF (ORA_IS_SERVERERROR (1986)) THEN
            DBMS_STANDARD.RAISE_APPLICATION_ERROR(-20999, 'this makes no sense', true);
        END IF;
      END CATCH01986;
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS;
    ORA-00604: error occurred at recursive SQL level 1
    ORA-20999: this makes no sense
    ORA-06512: at line 10
    ORA-01986: OPTIMIZER_GOAL is obsolete
    00604. 00000 -  "error occurred at recursive SQL level %s"
    *Cause:    An error occurred while processing a recursive SQL statement
               (a statement applying to internal dictionary tables).
    *Action:   If the situation described in the next error on the stack
               can be corrected, do so; otherwise contact Oracle Support.
    -- Client Application reports errorcode 604Test 4: Adding an EXCEPTION part to the trigger does not help, this will catch only exceptions raised while the trigger executes:
    CREATE OR REPLACE
    TRIGGER CATCH01986
      AFTER SERVERERROR
      ON SCHEMA
      BEGIN
        IF (ORA_IS_SERVERERROR (1986)) THEN
            DBMS_STANDARD.RAISE_APPLICATION_ERROR(-20999, 'this makes no sense', true);
        END IF;
      EXCEPTION
        WHEN OTHERS THEN
          NULL;
      END CATCH01986;
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS;
    ORA-01986: OPTIMIZER_GOAL is obsolete
    01986. 00000 -  "OPTIMIZER_GOAL is obsolete"
    *Cause:    An obsolete parameter, OPTIMIZER_GOAL, was referenced.
    *Action:   Use the OPTIMIZER_MODE parameter.
    -- Client Application reports errorcode 1986So i do not know what to do inside the trigger to clean the error stack so that the client will receive no errorcode.

  • Oracle 10g sql tuning

    I am on Oracle 10.2.0.3 on Windows 2003.
    I have a third party package whose code cannot be modified. There are several queries written using NOT clauses, as a result Oracle does full table scan and hash joins.
    select * from svp_view_s where NOT a_webc_url like '%dm_sig_source%.pdf' and
    r_object_id in (Select parent_id from svp_view_l where child_id='098c4230800d7dd7' and NOT
    a_webc_url like '%dm_sig_source%.pdf');
    Is there a way to force it in a generic fashion to use indexes instead of explicitly adding hints to use specific indexes. Oracle many times ignores the hints. Also I do not have access to code, so somehow has to figure out how to use stored outlines.
    There are many queries. I was looking at some generic solution.
    Prem

    Look into whether you can use the DBMS_ADVANCED_REWRITE built-in package.
    http://www.psoug.org/reference/dbms_adv_rewrite.html

  • Problem about advanced rewrite

    i build a advanced rewrite like:
    begin
    sys.dbms_advanced_rewrite.declare_rewrite_equivalence (
         name=> 'rewrite1',
         source_stmt =>
    'select * from testfy where con like ''%c%''',
         destination_stmt =>
    'select * from testfy where contains(con,''%c%'')>0',
         validate=> false,
         rewrite_mode=> 'text_match');
    end;
    but when i execute the query "select * from testfy where con like '%a%';"
    DB gave me a error:
    ERROR at line 1:
    ORA-03113: end-of-file on communication channel
    Process ID: 5280
    Session ID: 170 Serial number: 8
    Why?
    What should i do?

    What db version are you using? Runs without error on 11.1.0.7 but still I think it does not return the expected results:
    SQL> select * from v$version where rownum=1
    BANNER                                                                         
    Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production         
    1 row selected.
    SQL> drop index emp_txt_idx
    Index dropped.
    SQL> create index emp_txt_idx
       on emp (ename)
       indextype is ctxsys.context
    Index created.
    SQL> begin
       sys.dbms_advanced_rewrite.declare_rewrite_equivalence (
          name               => 'rewrite1',
          source_stmt        => 'select ename from emp where ename like ''%L%''',
          destination_stmt   => 'select ename from emp where contains(ename, ''%K%'') > 0',
          validate           => false,
          rewrite_mode       => 'text_match'
    end;
    PL/SQL procedure successfully completed.
    SQL> select ename from emp where ename like '%L%'
    ENAME    
    ALLEN    
    BLAKE    
    CLARK    
    MILLER   
    4 rows selected.

  • How to create outline from perfstat.stats$SQL_PLAN table

    How do I create outline (Plan stability in 10gR2database) from perfstat.stats$SQL_PLAN table?
    Current V$SQL_PLAN does not contain good but but week older snapshots have good plan.
    I can't modify query, it's vendor query so I need to create outline/plan stability.
    Thanks for help.

    user7478143 wrote:
    Thanks for reply.
    I'm not saying I find it out doc but here is situation.
    I have query which change execution plan week ago.
    I have perfstat enable and I found out good execution plan from perfstat.stat$SQL_PLAN view.
    If it's our query I can modify query and able to get good execution plan but it's vendor supplied query (which is Oracle - it used to be Portal now Oracle acquired it) so I can't modified it.
    All I'm trying to do is how do I generate good plan and assigned to vendor query's hash_value/sql_id.If DBMS_ADVANCED_REWRITE is not an option for you and you want to use an outline, there is one significant problem. The Statspack captured data does not include quite enough information, in particular the OTHER_XML column, and the access predicates. So, what can you do? Note that this script is from page 214 of the book that I co-authored. Let's say you execute this SQL statement:
    SQL> SELECT
      2    SQL_ID,
      3    COUNT(DISTINCT PLAN_HASH_VALUE) C
      4  FROM
      5    PERFSTAT.STATS$SQL_PLAN_USAGE
      6  GROUP BY
      7    SQL_ID
      8  HAVING
      9    COUNT(DISTINCT PLAN_HASH_VALUE)>1;
    SQL_ID         C
    0fr8zhn4ymu3v  2
    0h6b2sajwb74n  2
    1gu8t96d0bdmu  2
    39m4sx9k63ba2  2
    4b57myt9mpz37  3
    52tr7ay85qwn0  5
    …Interesting, SQL_ID has 2 different execution plans, let's take a look at the execution plans:
    SQL> SET LINESIZE 150
    SQL> SET PAGESIZE 10000
    SQL> SPOOL StatspackPlan.txt
    SQL> SELECT /*+ ORDERED */
      2    T.*
      3  FROM
      4    (SELECT DISTINCT
      5       PLAN_HASH_VALUE
      6     FROM
      7       PERFSTAT.STATS$SQL_PLAN_USAGE
      8     WHERE
      9       SQL_ID='0fr8zhn4ymu3v'
    10     ORDER BY
    11       PLAN_HASH_VALUE) SPU,
    12    TABLE(DBMS_XPLAN.DISPLAY(
    13      'PERFSTAT.STATS$SQL_PLAN',
    14      NULL,
    15      'TYPICAL -PREDICATE -NOTE',
    16      'PLAN_HASH_VALUE='||SPU.PLAN_HASH_VALUE)) T;
    | Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    |*  0 | SELECT STATEMENT            |            |       |       |     2 (100)|          |
    |*  1 |  TABLE ACCESS BY INDEX ROWID| OPQTYPE$   |     1 |    27 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | I_OPQTYPE1 |     1 |       |     1   (0)| 00:00:01 |
    | Id  | Operation             | Name     | Cost  |
    |*  0 | SELECT STATEMENT      |          |       |
    |*  1 |  SORT ORDER BY        |          |     0 |
    |*  2 |   TABLE ACCESS CLUSTER| OPQTYPE$ |       |
    |*  3 |    INDEX UNIQUE SCAN  | I_OBJ#   |       |
    --------------------------------------------------As can be seen by the above, in one case the I_OBJ# index was used, and in another case the I_OPQTYPE1 index was used. Let's assume that I_OPQTYPE1 is the most efficient access path, so a hint like this needs to be inserted (assuming that the table does not have an alias in the SQL statement:
    /*+ INDEX(OPQTYPE$ I_OPQTYPE1) */Now what (obviously, we would not want to actually fix the above plan for an internal SQL statement)? Take a look at the following, which shows how to build a private outline for the unhinted version of the SQL statement, an outline for a hinted version, and then swap the resulting outlines, followed by building a public outline from the hacked outline:
    http://hoopercharles.wordpress.com/2009/12/18/tracking-performance-problems-inserting-a-hint-into-sql-in-a-compiled-program/
    Charles Hooper
    Co-author of "Expert Oracle Practices: Oracle Database Administration from the Oak Table"
    http://hoopercharles.wordpress.com/
    IT Manager/Oracle DBA
    K&M Machine-Fabricating, Inc.

  • DBMS_ADVANCED_REQRITE getting ORA-00905: missing keyword

    What am I doing wrong here?
    17:17:29 NJ3417@pubd1> create table test_a (col_a varchar2(20));
    Table created.
    Elapsed: 00:00:00.04
    17:17:55 NJ3417@pubd1> insert into test_a values('Red');
    1 row created.
    Elapsed: 00:00:00.02
    17:18:09 NJ3417@pubd1> create table test_b (col_b varchar2(20));
    Table created.
    Elapsed: 00:00:00.02
    17:18:32 NJ3417@pubd1> insert into test_b values('Blue');
    1 row created.
    Elapsed: 00:00:00.03
    17:18:55 NJ3417@pubd1> commit;
    Commit complete.
    17:34:56 NJ3417@pubd1> begin
    17:34:56   2    sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
    17:34:56   3           name => 'Mikes SQL override',
    17:34:56   4           source_stmt => 'SELECT col_a FROM test_a',
    17:34:56   5           destination_stmt => 'SELECT col_b FROM test_b',
    17:34:56   6           validate => FALSE);
    17:34:56   7  end;
    17:34:56   8  /
    begin
    ERROR at line 1:
    ORA-00905: missing keyword
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 29
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 185
    ORA-06512: at line 2
    17:54:18 NJ3417@pubd1> select * from v$version;
    BANNER
    Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
    PL/SQL Release 11.2.0.3.0 - Production
    CORE    11.2.0.3.0      Production
    TNS for Solaris: Version 11.2.0.3.0 - Production
    NLSRTL Version 11.2.0.3.0 - Production
    5 rows selected.Thanks,
    Mike

    mtefft wrote:
    What am I doing wrong here?I don't have your exact version but I believe you can not have any string as the name of the rewrite rule. See the documentation
    Here is the working example:
    SQL> select * from v$version ;
    BANNER
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
    PL/SQL Release 11.2.0.1.0 - Production
    CORE    11.2.0.1.0      Production
    TNS for Linux: Version 11.2.0.1.0 - Production
    NLSRTL Version 11.2.0.1.0 - Production
    SQL> create table test_a (col_a varchar2(20));
    Table created.
    SQL> insert into test_a values('Red');
    1 row created.
    SQL> create table test_b (col_b varchar2(20));
    Table created.
    SQL> insert into test_b values('Blue');
    1 row created.
    SQL> commit ;
    Commit complete.
    SQL> select col_a from test_a ;
    COL_A
    Red
    SQL> select col_b from test_b ;
    COL_B
    Blue
    begin
      sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
           name => 'Mikes SQL override',
           source_stmt => 'SELECT col_a FROM test_a',
           destination_stmt => 'SELECT col_b FROM test_b',
           validate => FALSE);
    end;
      8  /
    begin
    ERROR at line 1:
    ORA-00905: missing keyword
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 29
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 185
    ORA-06512: at line 2
    begin
      sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
           name => 'myrule',
           source_stmt => 'SELECT col_a FROM test_a',
           destination_stmt => 'SELECT col_b FROM test_b',
           validate => FALSE);
    end;
      8  /
    PL/SQL procedure successfully completed.
    SQL> show parameter rewrite
    NAME                                 TYPE        VALUE
    query_rewrite_enabled                string      TRUE
    query_rewrite_integrity              string      enforced
    SQL> alter session set query_rewrite_integrity=trusted ;
    Session altered.
    SQL> show parameter rewrite
    NAME                                 TYPE        VALUE
    query_rewrite_enabled                string      TRUE
    query_rewrite_integrity              string      TRUSTED
    SQL> select col_a from test_a ;
    COL_A
    Blue

Maybe you are looking for

  • ICal birthday calendar from Tiger missing after upgrade

    Hi, I recently upgraded from Tiger to 10.6.7 Leopard.  I noticed that iCal did not import my Birthday's calendar that I had manually created in Tiger.  None of my birthdays show up except for one when I select "show birthday calendar" in iCal prefere

  • Web browsers taking 20 minutes to load.

    My web browser is taking about 20 minutes to load, whether it is IE, Chrome, or safari. this only started about 2 or 3 days ago. Is my modem dying, or is it the computer?

  • Cfldap to get 2 level of subordinates list from active directory

    <CFLDAP SERVER="ldap.com" PORT="333" START="O=COM,C=AN" SCOPE="SUBTREE" NAME="qryLevel1" ACTION="QUERY" ATTRIBUTES="cn, uid, alias" FILTER="(&(manager=cn=TestName,ou=employee,o=COM,c=an)(objectclass=olPerson))" MAXROWS="999999" TIMEOUT="90000"> By us

  • How to backup chat history in a messenger app

    I did buy a new iPhone 5. And when I went to Apple store to get my new order, I found all the chat history or document history in messenger or picture fixing apps were restored in my new iPhone 5. Please, anyone knows how to backup chat history in me

  • HELP! Have serial number for PSE8 but can't install?

    Just as the question says really, I lost my Photoshop Elements 8 disc and have the serial number but do not know where to retreive it from so I can install it. The product is registered with Adobe. Thanks, K