schemes of same bind variable

I used same set of values when the following SQL execution, but it seems that the plans are changed, can someone explain the cause of this behavior.


BANNER                                                                              CON_ID

-------------------------------------------------------------------------------- ----------

Database Oracle 12 c Enterprise Edition Release 12.1.0.1.0 - 64 bit Production 0

PL/SQL Release 12.1.0.1.0 - Production 0

CORE 12.1.0.1.0 Production 0

AMT for Linux: Version 12.1.0.1.0 - Production 0

NLSRTL Version 12.1.0.1.0 - Production 0

Select table_name, column_name, histogram, num_distinct dba_tab_col_statistics where table_name = 'TEMP' and column_name = 'FILE_ID ';

TABLE_NAME COLUMN_NAME NUM_DISTINCT HISTOGRAM

-------------------- -------------------- ------------ ---------------

FILE_ID TEMP 5 FREQUENCY

TABLE_NAME COLUMN_NAME ENDPOINT_VALUE

-------------------- -------------------- --------------

FILE_ID TEMP 1

FILE_ID TEMP 3

FILE_ID TEMP 4

FILE_ID TEMP 6

FILE_ID TEMP 8

TABLE_NAME SAMPLE_SIZE NUM_ROWS

-------------------- ----------- ----------

9569280 9569280 TEMP

Connected.

SQL > variable x number;

SQL > set line 120

SQL > set autotrace on explain

SQL > col for a20 owner

SQL > exec: x: = 4

PL/SQL procedure successfully completed.

SQL > select owner, count (*) temp where file_id = 4 groups by order of owner by 2;

OWNER COUNT (*)

-------------------- ----------

SYS 109568

Execution plan

----------------------------------------------------------

Hash value of plan: 3296224485

----------------------------------------------------------------------------------------------

| ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |

----------------------------------------------------------------------------------------------

|  0 | SELECT STATEMENT |      |    16.  144.  2794 (1) | 00:00:01 |

|  1.  SORT ORDER BY |      |    16.  144.  2794 (1) | 00:00:01 |

|  2.  HASH GROUP BY.      |    16.  144.  2794 (1) | 00:00:01 |

|  3.    TABLE ACCESS BY ROWID INDEX BATCH | TEMP |  109K |  963K |  2790 (1) | 00:00:01 |

|*  4 |    INDEX RANGE SCAN | IDX |  114K |      |  331 (1) | 00:00:01 |

----------------------------------------------------------------------------------------------

Information of predicates (identified by the operation identity card):

---------------------------------------------------

4 - access ("FILE_ID" = 4)

SQL > select owner, count (*) temp where file_id =: x group by order of owner by 2.

OWNER COUNT (*)

-------------------- ----------

SYS 109568

Execution plan

----------------------------------------------------------

Hash value of plan: 386304853

----------------------------------------------------------------------------

| ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |

----------------------------------------------------------------------------

|  0 | SELECT STATEMENT |      |    16.  144. 44628 (1) | 00:00:02 |

|  1.  SORT ORDER BY |      |    16.  144. 44628 (1) | 00:00:02 |

|  2.  HASH GROUP BY.      |    16.  144. 44628 (1) | 00:00:02 |

|*  3 |    TABLE ACCESS FULL | TEMP |  1913 K |    16 M | 44538 (1) | 00:00:02 |

----------------------------------------------------------------------------

Information of predicates (identified by the operation identity card):

---------------------------------------------------

3 filter ('FILE_ID' = TO_NUMBER (:X))

Hello

A few notes:

(1) SQL > set autotrace on explain

(2) from running with the literal:

Information of predicates (identified by the operation identity card):

---------------------------------------------------

4 - access ("FILE_ID" = 4)

(3) from running with bind:

Information of predicates (identified by the operation identity card):

---------------------------------------------------

3 - filter ("FILE_ID" =TO_NUMBER(:X))

See how you have a to_number() in there? It of the autotrace behavior and would explain the difference in the execution plan.

You can find more information search on the web, but a good starting point is here for information additional (Jonathan Lewis - Oracle Notepad):

AutoTrace tip | Notebook of the Oracle

Kind regards

Mark

Tags: Database

Similar Questions

  • Bind Variables and using the keyword

    In my dynamic SQL, I use the same variable in several places in my query. Is there a way to avoid rewriting the same value multiple times in the list of arguments to bind? It is something like that - only pseudo code.
    DECLARE
    tSQL VARCHAR2(99)
    pVal INT := 2;
    
    BEGIN
    tSQL := 
               'SELECT * ' ||
               '  FROM dual ' ||
               ' WHERE col1 =: iVal ' ||
               '   AND col2 IN (SELECT col2 ' ||
               '                  FROM dual  ' ||
               '                 WHERE col1 =: iVal) ' ||
               ' UNION ' ||
               ' SELECT * ' ||
               '   FROM dual ' ||
               '  WHERE col1 =: iVal';
    
    EXECUTE IMMEDIATE tSQL 
    USING pVal, pVal, pVal;  -- Is there a way to avoid having to rewrite the same bind variable argument three times since the value is the same?
    
    END;
    Is there a way to avoid having to rewrite the same argument three times bind variable as the value is the same?

    Etbin wrote:
    http://docs.Oracle.com/CD/E11882_01/AppDev.112/e25519/dynamic.htm#BHCHIHEJ says:
    Placeholders are associated with bind variable in the USING clause of position, and not by name.

    Concerning

    Etbin

    The exception to this rule is if the SQL statement is an anonymous block or a call statement. In this case, the repetition of the names of the placeholder is significant.

    http://docs.Oracle.com/CD/E11882_01/AppDev.112/e25519/dynamic.htm#CHDFHEAG

    For example, the following will fail with ORA-01008: not all variables

    declare
     v_cnt number;
    begin
      execute immediate 'select count(*) from dual where 1 = :B1 and 2 > :B1'
      into v_cnt using 1;
      dbms_output.put_line(v_cnt);
    end;
    

    However, the following will succeed because the SQL code is in fact an anonymous block:

    begin
      execute immediate 'declare
                           v_cnt number;
                         begin
                           select count(*)
                           into v_cnt
                           from dual
                           where 1 = :B1 and 2 > :B1;
                           dbms_output.put_line(v_cnt);
                         end;'
      using 1;
    end;
    

    Pretty cool stuff.

  • Histograms and bind variables

    Hi guys,.
    When a SQL using bind variables histograms afftect the excution plan how?

    For example
    There is a table 'TEST' a column a number, varchar2 (100) b, c. tank (100).
    100000 rows in this table and the 90000 column rows a value is 1, the other value is 2-10 by 100rows.

    Now this column a histogram and a btree index only has on a;

    Here is sample code
    number of a_v var;
    exec: a_v: = 10;

    Select * from test where a =: a_v.

    The plan of the excution is full table scan.

    If I don't use of variable binding. It will scan the index.


    I remember that a document mentioned that "do not use histograms using bind variables.

    But why?

    I disabled same bind variable peeking?


    Thank you guys. Looking forward to your response.

    Longfei Wei says:
    Thanks Centinul this article is useful for me, but it is not explained why histograms do not work well with bind variables.

    Thanks again.

    Longfei,

    Jonathan Lewis article is very good - another look at this article. Histograms peuvent work with bind variable, but the end result is usually not the desired result. Bind variables are used to reduce the number of different execution plans. The histograms are used to find what is supposed to be the best execution plan for the predicates provided and in the case of the bind variables, those are peeked from the bind variable values. Thus, if you have a histogram on a column and for hard analysis of a SQL statement and the most common value in this column is presented in the binding variable - this execution plan is considered by the optimizer to be the 'best' execution plan for the bind variable values provided. Suppose now that instead the less popular value in the column is specified - the optimizer peut produce a very different for the same SQL statement execution plan, which is optimized for the less popular value (this can be a scan of the index systematic range, rather than a full table scan). Now suppose the execution plan may not change when change of variable values bind - if you have a single popular value and many unpopular values, if the analysis lasts is performed with the popular single value, you might find that all subsequent runs of this SQL statement to perform full table scans, even if only a few rows in the table are selected.

    Here's a quick test on the Oracle 11.2.0.2 database to demonstrate:

    CREATE TABLE T1 (
      C1 NUMBER,
      C2 NUMBER,
      C3 VARCHAR2(300));
    
    INSERT INTO
      T1
    SELECT
      *
    FROM
      (SELECT
        ROWNUM C1,
        DECODE(MOD(ROWNUM,100),99,99,1) C2,
        RPAD('A',300,'A') C3
      FROM
        DUAL
      CONNECT BY
        LEVEL <= 1000000)
    ORDER BY
      C2;
    
    CREATE INDEX IND_T1_C2 ON T1(C2);
    
    EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>USER,TABNAME=>'T1',CASCADE=>TRUE,METHOD_OPT=>'FOR ALL INDEXED COLUMNS SIZE 254')
    

    The foregoing has created a table with 1 000 000 lines where 99% of the lines have a value of 1 in C2 and 1% have a value of 99, and lines are inserted with a perfect setting in cluster factor because of the ORDER BY clause. A histogram has been created on the indexed column.

    Let's try a test, we'll search a unpopular value 2 for the connection variable:

    VARIABLE N1 NUMBER
    EXEC :N1:=2
    
    SELECT /*+ GATHER_PLAN_STATISTICS */
      C1,
      C2
    FROM
      T1
    WHERE
      C2 = :N1;
    
    no rows selected
    
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'ALLSTATS LAST'));
    
    SQL_ID  c7su63uw7nch6, child number 0
    -------------------------------------
    SELECT /*+ GATHER_PLAN_STATISTICS */   C1,   C2 FROM   T1 WHERE   C2 =
    :N1
    
    Plan hash value: 236868917
    
    ------------------------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
    ------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |      1 |        |      0 |00:00:00.01 |       3 |      1 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1        |      1 |   5957 |      0 |00:00:00.01 |       3 |      1 |
    |*  2 |   INDEX RANGE SCAN          | IND_T1_C2 |      1 |   5957 |      0 |00:00:00.01 |       3 |      1 |
    ------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("C2"=:N1)
    

    Thus, there is no selected row, the optimizer predicts that 5 957 lines would be returned and a path to the index has been selected. Path of this index would also be appropriate for the value of the bind variable 1? We will continue the trial, this time by choosing the 99 for the binding variable value:

    EXEC :N1:=99
    SET TIMING ON
    
    SELECT /*+ GATHER_PLAN_STATISTICS */
      C1,
      C2
    FROM
      T1
    WHERE
      C2 = :N1;
    
    ...
    10000 rows selected.
    
    Elapsed: 00:00:05.35
    
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'ALLSTATS LAST'));
    
    SQL_ID  c7su63uw7nch6, child number 0
    -------------------------------------
    SELECT /*+ GATHER_PLAN_STATISTICS */   C1,   C2 FROM   T1 WHERE   C2 =
    :N1
    
    Plan hash value: 236868917
    
    ---------------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |      1 |        |  10000 |00:00:00.02 |    1783 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1        |      1 |   5957 |  10000 |00:00:00.02 |    1783 |
    |*  2 |   INDEX RANGE SCAN          | IND_T1_C2 |      1 |   5957 |  10000 |00:00:00.01 |     690 |
    ---------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("C2"=:N1)
    

    Once more, the optimizer predicts 5 957 lines could be found even if 10,000 rows have been retrieved. Note also that the number of children is always 0. We will continue the trial, this time with the bind variable value of 1:

    EXEC :N1:=1
    
    SET AUTOTRACE TRACEONLY STATISTICS
    
    SELECT /*+ GATHER_PLAN_STATISTICS */
      C1,
      C2
    FROM
      T1
    WHERE
      C2 = :N1;
    
    990000 rows selected.
    
    Elapsed: 00:00:18.78
    
    Statistics
    ---------------------------------------------------
              1  recursive calls
              1  db block gets
         108571  consistent gets
              0  physical reads
             96  redo size
       21958348  bytes sent via SQL*Net to client
         726508  bytes received via SQL*Net from client
          66001  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
         990000  rows processed
    
    SET AUTOTRACE OFF
    

    Because I used AUTOTRACE to prevent 990 000 lines scrolling on the screen, I have to specify the SQL_ID and CHILD_NUMBER to retrieve the execution plan:

    
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('c7su63uw7nch6',0,'ALLSTATS LAST'));
    
    SQL_ID  c7su63uw7nch6, child number 0
    -------------------------------------
    SELECT /*+ GATHER_PLAN_STATISTICS */   C1,   C2 FROM   T1 WHERE   C2 =
    :N1
    
    Plan hash value: 236868917
    
    ---------------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |      1 |        |  10000 |00:00:00.02 |    1783 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1        |      1 |   5957 |  10000 |00:00:00.02 |    1783 |
    |*  2 |   INDEX RANGE SCAN          | IND_T1_C2 |      1 |   5957 |  10000 |00:00:00.01 |     690 |
    ---------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("C2"=:N1)
    

    Who can be the execution plan that was used because it shows that 10,000 rows have been retrieved. We will try again, this time with CHILD_NUMBER 1:

    
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('c7su63uw7nch6',1,'ALLSTATS LAST'));
    
    SQL_ID  c7su63uw7nch6, child number 1
    -------------------------------------
    SELECT /*+ GATHER_PLAN_STATISTICS */   C1,   C2 FROM   T1 WHERE   C2 =
    :N1
    
    Plan hash value: 3617692013
    
    ------------------------------------------------------------------------------------
    | Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |      1 |        |    990K|00:00:00.83 |     108K|
    |*  1 |  TABLE ACCESS FULL| T1   |      1 |    988K|    990K|00:00:00.83 |     108K|
    ------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("C2"=:N1)
    

    The foregoing shows the actual plan that has been used. Sharing the adjustment slider (first available with Oracle Database 11.1) is reached and forced to re-evaluate the execution plan to avoid a very slow recovery through the index - which won't happen before 11.1 database Oracle.

    Just to illustrate:

    ALTER SESSION SET OPTIMIZER_FEATURES_ENABLE='10.2.0.4';
    
    VARIABLE N1 NUMBER
    EXEC :N1:=2
    
    SELECT /*+ GATHER_PLAN_STATISTICS */
      C1,
      C2
    FROM
      T1
    WHERE
      C2 = :N1;
    
    no rows selected
    
    Elapsed: 00:00:00.00
    
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'ALLSTATS LAST'));
    
    SQL_ID  c7su63uw7nch6, child number 2
    -------------------------------------
    SELECT /*+ GATHER_PLAN_STATISTICS */   C1,   C2 FROM   T1 WHERE   C2 =
    :N1
    
    Plan hash value: 236868917
    
    ---------------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |      1 |        |      0 |00:00:00.01 |       3 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1        |      1 |   5957 |      0 |00:00:00.01 |       3 |
    |*  2 |   INDEX RANGE SCAN          | IND_T1_C2 |      1 |   5957 |      0 |00:00:00.01 |       3 |
    ---------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("C2"=:N1)
    

    Note in the above that the CHILD_NUMBER is now 2.

    Continues:

    EXEC :N1:=99
    SET TIMING ON
    
    SELECT /*+ GATHER_PLAN_STATISTICS */
      C1,
      C2
    FROM
      T1
    WHERE
      C2 = :N1;
    
    10000 rows selected.
    
    Elapsed: 00:00:05.31
    
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'ALLSTATS LAST'));
    
    SQL_ID  c7su63uw7nch6, child number 2
    -------------------------------------
    SELECT /*+ GATHER_PLAN_STATISTICS */   C1,   C2 FROM   T1 WHERE   C2 =
    :N1
    
    Plan hash value: 236868917
    
    ---------------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |      1 |        |  10000 |00:00:00.02 |    1783 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1        |      1 |   5957 |  10000 |00:00:00.02 |    1783 |
    |*  2 |   INDEX RANGE SCAN          | IND_T1_C2 |      1 |   5957 |  10000 |00:00:00.01 |     690 |
    ---------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("C2"=:N1)
    

    The CHILD_NUMBER is always 2.

    Continues:

    EXEC :N1:=1
    
    SET AUTOTRACE TRACEONLY STATISTICS
    
    SELECT /*+ GATHER_PLAN_STATISTICS */
      C1,
      C2
    FROM
      T1
    WHERE
      C2 = :N1;
    
    990000 rows selected.
    
    Elapsed: 00:00:16.91
    
    Statistics
    ---------------------------------------------------
              0  recursive calls
              0  db block gets
         175927  consistent gets
              0  physical reads
              0  redo size
       21958348  bytes sent via SQL*Net to client
         726508  bytes received via SQL*Net from client
          66001  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
         990000  rows processed
    
    SET AUTOTRACE OFF
    
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('c7su63uw7nch6',2,'ALLSTATS LAST'));
    
    SQL_ID  c7su63uw7nch6, child number 2
    -------------------------------------
    SELECT /*+ GATHER_PLAN_STATISTICS */   C1,   C2 FROM   T1 WHERE   C2 =
    :N1
    
    Plan hash value: 236868917
    
    ---------------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |      1 |        |    990K|00:00:01.63 |     175K|
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1        |      1 |   5957 |    990K|00:00:01.63 |     175K|
    |*  2 |   INDEX RANGE SCAN          | IND_T1_C2 |      1 |   5957 |    990K|00:00:00.68 |   67932 |
    ---------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("C2"=:N1)
    

    The foregoing is the execution plan for CHILD_NUMBER 2 - notice that this time he reports 990 000 recovered lines, it's the execution that was used - adaptive cursor sharing plan do not have take effect and force the re-evaluation of the implementation plan - implementation plan has NOT been changed for a full table scan. That's the risk you take if you allow histograms on columns that have an uneven distribution of values and bind variables are used in the WHERE clause that refers to the column.

    Charles Hooper
    Co-author of "Expert Oracle practices: Oracle Database Administration of the Oak Table.
    http://hoopercharles.WordPress.com/
    IT Manager/Oracle DBA
    K & M-making Machine, Inc.

  • Estimate of poor cardinality using Bind Variables

    Hi I'm using the 11.2.0.4.0 Oracle version. I have a query that is underway for the plan of the poor execution by the estimate of poor cardinality for two tables (I've extracted and published this part only) as I mentioned below, the individual conditions for which the estimate goes bad and moving entire query execution path.

    These are for two tables and currently we use BIND variable for them in our code, and I notice, its best estimate gives with literals. I need to know how to handle this scenario that I need this query to execute for all types of volumes. Is there something I can do without changing the code, as it works well for most of the execution? In the current scenario of the main query that uses those below tables providing a plan (index + nested loop) that works very well for small volume, but running for 10 hr + for large volume as ideally its going to the same regime.
    And Yes, most time that this request will be hit for small volume, but killing some appearance of large volume presents the performance of the queries.


    Here are the values of the variable binding.

    B1 VARIABLE VARCHAR2 (32);
    B2 VARIABLE VARCHAR2 (32);
    B3 VARIABLE NUMBER;
    B4 VARIABLE VARCHAR2 (32);
    B7 VARIABLE VARCHAR2 (32);
    B5 VARIABLE NUMBER;
    B6 VARIABLE NUMBER;

    EXEC: B1: = 'NONE ';
    EXEC: B2: = NULL;
    EXEC: B3: = 0;
    EXEC: B4: = NULL;
    EXEC: B7: = NULL;
    EXEC: B5: = 0;
    EXEC: B6: = 0;

    ---- For  TABLE1-------
     -- Published Actual VS Etimated cardinality
     
     
    -- With bind values
    select * from TABLE1 SF
    WHERE (   (SF.C1_IDCODE = :B4) OR (NVL (:B4, 'NONE') = 'NONE'))
        AND ( (SF.C2_ID = :B3) OR (NVL (:B3, 0) = 0));
    Plan hash value: 2590266031
    -----------------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation                 | Name                | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
    -----------------------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT          |                     |      1 |        |  28835 |00:00:00.08 |    2748 |     46 |       |       |          |
    |*  1 |  TABLE ACCESS STORAGE FULL| TABLE1              |      1 |     11 |  28835 |00:00:00.08 |    2748 |     46 |  1025K|  1025K|          |
    -----------------------------------------------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - storage((("SF"."C1_IDCODE"=:B4 OR NVL(:B4,'NONE')='NONE') AND ("SF"."C2_ID"=:B3 OR NVL(:B3,0)=0)))
           filter((("SF"."C1_IDCODE"=:B4 OR NVL(:B4,'NONE')='NONE') AND ("SF"."C2_ID"=:B3 OR NVL(:B3,0)=0))) 
     
    -- With literals 
    select * from TABLE1 SF
     WHERE  (   (SF.C1_IDCODE = null) OR (NVL (null, 'NONE') = 'NONE'))
          AND ( (SF.C2_ID = 0) OR (NVL (0, 0) = 0));
       Plan hash value: 2590266031
    --------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation                 | Name                | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    --------------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT          |                     |      1 |        |  28835 |00:00:00.03 |    2748 |       |       |          |
    |   1 |  TABLE ACCESS STORAGE FULL| TABLE1              |      1 |  28835 |  28835 |00:00:00.03 |    2748 |  1025K|  1025K|          |
    --------------------------------------------------------------------------------------------------------------------------------------
    
    --------For TABLE2 ----------------------- 
    -- Published Autotrace plan, as it was taking long time for completion, and actual cardinality is 45M, but its estimating 49 With bind value---
    
    --withbind value
    select * from TABLE2 MTF
    WHERE (   (MTF.C6_CODE = TRIM (:B2)) OR (NVL (:B2, 'NONE') = 'NONE'))
      AND (   (MTF.C3_CODE = :B1)  OR (NVL (:B1, 'NONE') = 'NONE'))
      AND (   (MTF.C4_CODE = :B7)  OR (:B7 IS NULL))
      AND (   (MTF.C5_AMT <= :B6)  OR (NVL (:B6, 0) = 0))
      AND (   (MTF.C5_AMT >= :B5)  OR (NVL (:B5, 0) = 0));
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1536592532
    -----------------------------------------------------------------------------------------------------------
    | Id  | Operation                  | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    -----------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT           |              |    49 | 10437 |   358K  (1)| 01:11:43 |       |    |
    |   1 |  PARTITION RANGE ALL       |              |    49 | 10437 |   358K  (1)| 01:11:43 |     1 |  2 |
    |*  2 |   TABLE ACCESS STORAGE FULL| TABLE2       |    49 | 10437 |   358K  (1)| 01:11:43 |     1 |  2 |
    -----------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - storage(("MTF"."C4_CODE"=:B7 OR :B7 IS NULL) AND ("MTF"."C3_CODE"=:B1 OR
                  NVL(:B1,'NONE')='NONE') AND ("MTF"."C5_AMT"<=TO_NUMBER(:B6) OR NVL(:B6,0)=0) AND
                  ("MTF"."C5_AMT">=TO_NUMBER(:B5) OR NVL(:B5,0)=0) AND ("MTF"."C6_CODE"=TRIM(:B2) OR
                  NVL(:B2,'NONE')='NONE'))
           filter(("MTF"."C4_CODE"=:B7 OR :B7 IS NULL) AND ("MTF"."C3_CODE"=:B1 OR
                  NVL(:B1,'NONE')='NONE') AND ("MTF"."C5_AMT"<=TO_NUMBER(:B6) OR NVL(:B6,0)=0) AND
                  ("MTF"."C5_AMT">=TO_NUMBER(:B5) OR NVL(:B5,0)=0) AND ("MTF"."C6_CODE"=TRIM(:B2) OR
                  NVL(:B2,'NONE')='NONE'))
      
    -- with literal
    select * from TABLE2 MTF
    WHERE (   (MTF.C6_CODE = TRIM (null)) OR (NVL (null, 'NONE') = 'NONE'))
     AND (   (MTF.C3_CODE = 'NONE') OR (NVL ('NONE', 'NONE') = 'NONE'))
      AND (   (MTF.C4_CODE = null)  OR (null IS NULL))
       AND (   (MTF.C5_AMT <= 0)  OR (NVL (0, 0) = 0))
      AND (   (MTF.C5_AMT >= 0)  OR (NVL (0, 0) = 0));
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1536592532
    -----------------------------------------------------------------------------------------------------------
    | Id  | Operation                  | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    -----------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT           |              |    45M|  9151M|   358K  (1)| 01:11:41 |       |    |
    |   1 |  PARTITION RANGE ALL       |              |    45M|  9151M|   358K  (1)| 01:11:41 |     1 |  2 |
    |   2 |   TABLE ACCESS STORAGE FULL| TABLE2 |    45M|  9151M|   358K  (1)| 01:11:41 |     1 |  2 |
    -----------------------------------------------------------------------------------------------------------
    
    select column_name,num_nulls,num_distinct,density
    from dba_tab_col_statistics where table_name='TABLE2'
    and column_name in ('C3_CODE','C4_CODE','C5_AMT','C6_CODE');
    C3_CODE 0 65 0.0153846153846154
    C4_CODE 0 2 0.5
    C5_AMT 0 21544 4.64166357222429E-5
    C6_CODE 1889955 71 0.0140845070422535
    
    

    933257 wrote:

    ((SF. C1_IDCODE =: B4) OR (NVL (: B4, 'NONE') = 'NONE'))

    In fact for literals, I did not find any section of the predicate after running the sql code with activation "set autotrace traceonly explain."

    The main problem is with another large query whose cardinality is underestimated due to the presence of these table (table1, table2) with the above mentioned clause, and the query is for the analysis of index + nested with values of Bind loops and take 10 hr +, whereas with literals, its completion in ~ 8minutes with FTS + Hash Join.

    Your real problem is that you try to have just a single SQL query handle all POSSIBLE thanks to the use of embedded FILTERS ' either / or ' filters in the WHERE clause.  You want only a select this OPTION to run whatever filters have been selected at run time by the user or the application using it.  And it would never work.  You really need to SELECT different queries for different combinations of filter conditions.

    Why?  Think for a minute.  How Oracle works internally?  A SQL SELECT query gets analyzed and an execution plan is produced which is stored in the library cache and gets REUSED on all subsequent executions of this query - except in certain cases where there may exist several plans run through several cursors of the child.  So with only SELECT a query you only AN execution plan in the library cache, to be used by all THE executions of this query, regardless of the value of your run-time binding variables.

    Lets put another way - each library cache execution plan is associated with a SQL statement.  If you want a DIFFERENT execution plan then you need run a DIFFERENT SQL statement.  That's how you get a different execution plan - by running a different SQL statement.  Running the SAME SQL query generally you will get the SAME execution plan every time.

    In addition, because of the "either / or" filters that you use you will end up generally with a full Table Scan on each of the referenced tables.  Why?  Given that the optimizer must produce an implementation plan that manages all possible contingencies for all values of possible bind variables in the SELECT.  If the optimizer should choose to use any index based on one of these "either / or" filters then it would only help performance when real value was provided, but it would be really bad if a NULL value was supplied.  If the optimizer ends up ignoring the index because they are not always optimal for all possible input values and instead chose a plan that is "good enough" for all input values possible.  That means that it will use a scanning Table full.

    I hope you can see that it is precisely what is happening for you with your query.  You select this OPTION to manage the different combinations of filter, which leads to the execution plan only one, which leads to scans full Table on the referenced tables in these ' either / or ' filters.

    The solution?  Build queries SELECT DIFFERENT when input values are NULL.  How you do that?  Read this article to ask Tom that tells you:

    http://www.Oracle.com/technetwork/issue-archive/2009/09-Jul/o49asktom-090487.html

    To sum up - when you have real value for a bind variable 'bind_var1' add the following filter to your CHOICE:

    AND column_name1 =: bind_var1

    When the binding variable is NULL, add the filter according to your CHOICE:

    AND (1 = 1 OR: bind_var1 IS NULL)

    Now, you'll have 2 queries SELECT must be performed, which have exactly the same number of variables in the same order bind, which is important.  When you then run one of these variations, Oracle can analyze and optimize each one SEPARATELY, with a single execution by the SELECT query plan.

    When you provide a real value, the filter is a normal 'column = value' that the optimizer can use all indexes on this column, because NULL values are not referenced.

    When there is no real value, the optimizer will analyze the '1 = 1 GOLD' and realize that "1 = 1" is set to TRUE and GOLD, it is quite TRUE regardless because the binding variable is null or not.  This means that the optimizer will actually REMOVE this filter, because it filters nothing because it is always TRUE.  You will end up with an operating plan based on the other filters in the query, which is what you want because you have no filter on this column.

    What is it - producing distinct SELECT queries to determine if you have a real value to filter or not you end up with DIFFERENT execution plans for each of them, and each of them is OPTIMAL for this particular set of filters.  Now you get good performance for each variation of the performance of the SELECTION, rather than sometimes good and sometimes very bad when using SELECT only one.  It is impossible to try to get multiple shots of execution 'optimal' out of a SELECT query.  That's why you get mediocre performance under different bound the values of the variables.

    John Brady

  • Estimates of cardinality for index range scan with bind variables

    Oracle 11.2.0.4

    I am struggling to explain that the cardinality estimates for a scan of the index systematic range when using the bind variable.

    Consider the following query:

    SELECT /*+ INDEX(t1) */ *
    FROM   t1
    WHERE  source_id <= ?;
    
    

    Cardinalities for the INDEX RANGE SCAN and ACCESS of the TABLE are the same for different literal predicates, for example, source_id < = 5:

    ------------------------------------------------------------------------------------
    | Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |      |    50 |   350 |    12   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1   |    50 |   350 |    12   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | IX1  |    50 |       |     2   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("SOURCE_ID"<=5)
    
    

    If a variable binding is used instead of a literal, the overall selectivity is 5%. However, why the optimizer based on CSSTidy gives a cardinality estimated 11 for the scan of the index systematic range? As with the predicates literal, surely the cardinalities of the index range scan and access table should be the same?

    ------------------------------------------------------------------------------------
    | Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |      |    50 |   350 |     5   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1   |    50 |   350 |     5   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | IX1  |    11 |       |     2   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("SOURCE_ID"<=TO_NUMBER(:A))
    
    

    Unit test code:

    CREATE TABLE t1
    ( id NUMBER
    , source_id NUMBER
    );
    
    CREATE INDEX ix1 ON t1 (source_id);
    
    INSERT INTO t1
    SELECT level
         , ora_hash(level,99)+1
    FROM   dual
    CONNECT BY level <= 1000;
    
    exec DBMS_STATS.GATHER_TABLE_STATS(user,'T1')
    
    EXPLAIN PLAN FOR
    SELECT /*+ INDEX(t1) */ *
    FROM   t1
    WHERE  source_id <= 5;
    SELECT * FROM TABLE(dbms_xplan.display);
    
    EXPLAIN PLAN FOR
    SELECT /*+ INDEX(t1) */ *
    FROM   t1
    WHERE  source_id <= :a;
    SELECT * FROM TABLE(dbms_xplan.display);
    
    

    There are various places where the optimizer uses an assumption, and lie unpeekable (and of Villa "unknowable value") introduced guess.

    For unpeekable binds the conjecture for column<= {unknown}="" is="" 5%="" for="" table="" access="" (hence="" 50="" rows="" out="" of="" 1,000),="" but="" it's="" 0.009="" for="" index_column=""><= {unknown},="" which="" means="" i="" was="" expecting="" to="" see="" 9="" as="" the="" row="" estimate="" on="" the="" index="" range="">

    I just ran some quick tests, and EXPLAIN the PLAN seems to just use 0.011 selectivity in this case (in different versions of Oracle) although if we do the bind variable unpeekable at run time (and sample dynamic block etc.) optimization for execution is 0.009%.

    Concerning

    Jonathan Lewis

    Update: and this is a very old reference to the 0.009 (and 0.0045 for ' between the ' when it is applied to a clue: cost based Oracle - access Chapter 4 single B-tree )

  • Bind Variables on the view objects child definition

    JDeveloper 12 c

    I have an interesting question.  I have a view (AisWebModulePrivsVO) object that uses a bindvariable hardcoded in the view object.

    SELECT * FROM SYS. DBA_ROLE_PRIVS where DEALER =: bvUserName

    If I put this in the request module I can programmatically set the variable binding (view object contains the getter/setter for the binding variable).

    AisWebModulePrivsVOImpl voTest = am.getAisWebModulePrivsVI ();

    voTest.setbvUserName ("ARAWLS");

    voTest.executeQuery ();

    System.out.println ("test reports:" + voTest.getRowCount ());

    and get the correct number of records based on return on the user and database roles. If it works.

    What does NOT work, it is when this display object is a recording of 'the child' to another display object (as specified by a link between the two and by setting the object from a point of view as one child of the other in the module of the application).

    AppModule looks like this:

    CgRefCodesVO

    AisWebModulePrivsVO

    In this case, I have a view called cgRefCodeVO parent object.  There is a link between this and the AisWebModulePrivsVO. The relationship works.

    AISMenuAppModuleImpl m = ADFUtils.getApplicationModuleForDataControl (appMod) (AISMenuAppModuleImpl);

    CgRefCodesVOImpl cgRefVO = am.getCgRefCodes1 ();

    AisWebModulePrivsVOImpl modsVO = am.getAisWebModulePrivs1 ();

    modsVO.setbvDBUserName ("ARAWLS");  This doesn't seem to work here...

    cgRefVO.executeQuery ();

    All lines rs = cgRefVO.getRowSet ();

    RS. Reset();

    While (rs.hasNext ()) {}

    CgRefCodesVORowImpl CgRefRow = rs.next ((CgRefCodesVORowImpl));

    System.out.println ("RvLowValue:" + CgRefRow.getAttribute ("RvLowValue"));

    RowIterator aisModulesRowIter = CgRefRow.getAisWebModulePrivs ();

    System.out.println ("number of children:" + aisModulesRowIter.getRowCount ());

    }

    The code compiles and runs.  She translates: "County of the child: 0" for each row returned by the

    I also tried:

    VM VariableValueManager = modsVO.ensureVariableManager ();

    vm.setVariableValue ("bvDBUserName", "ARAWLS");

    And:

    modsVO.setNamedWhereClauseParam ("bvDBUserName", "ARAWLS");

    and (of https://community.oracle.com/message/2746551#2746551 ( )

    @Override

    protected void executeQueryForCollection (Object, object, Object [] object2, int i) {}

    I coded everything hard to see if it would work.

    setNamedWhereClauseParam ("bvDBUserName", "ARAWLS");

    super.executeQueryForCollection (object, object2, i);

    }

    and from there, I changed around the order to execute the objects in view.    https://community.oracle.com/message/10632314#10632314

    How can I set the variable binding in the object view child?

    Thank you

    Stuart

    It is an interesting example how ADF works up to a certain point... then you need to start to make cuts to modify its behavior as you wish.

    I decided that it was just easier to delete 'the child' parent (in the app module) and create a view of criteria on this subject for what would basically query the records to get the same results, like a child.

    Perhaps not as elegant, but so much easier.

    Thanks for your help.

    Stuart

  • Passing literal as a bind variable in Jena

    Hi all

    We are able to use bind variable with the id RDFVID. However, if we want to check for a literal using the jena/joseki adapter we are not able to perform the same operation. In our case the literal is of type string.

    We use:

    * WLS 12.1.0.3.

    * Adapter Jena 2.11.1.

    * Joseki 3.4.4.

    * ARQ 2.9.2.

    We try to run the following query on the stop of joseki.

    PREFIX foaf: http://xmlns.com/FOAF/0.1/ >

    PREFIX vcard: http://www.w3.org/2001/vCard-RDF/3.0# >

    PREFIX xsd: http://www.w3.org/2001/XMLSchema# >

    PREFIX oext: < http://Oracle.com/Semtech/Jena-adaptor/ext/function# >

    PREFIX ORACLE_SEM_FS_NS: http://Oracle.com/Semtech#no_fall_back, ALLOW_DUP = T, s2s >

    PREFIX ORACLE_SEM_HT_NS: http://Oracle.com/Semtech#monitor >

    PREFIX ORACLE_SEM_UEAP_NS: http://oracle.com/semtech#f$ RDFVID % 20 (ORACLE_ORARDF_RES2VID(?)) >

    PREFIX ORACLE_SEM_UEPJ_NS: http://Oracle.com/Semtech#f $RDFVID >

    PREFIX ORACLE_SEM_UEBV_NS: http://Oracle.com/Semtech# 'Lee' >

    SELECT? f

    WHERE

    {graph? g {? vcard:N p? vn.}}

    ? VN vcard:Family? f.

    ? FOAF:title p 'Sen'.}

    }

    The result set is empty. Replace the line 'ORACLE_SEM_UEBV_NS PREFIX: <http://oracle.com/semtech# "Lee"> "by any Variant is to be given an error or the empty set. (Some variants (& quot;)) Lee & quot; Lee, "Lee" & #39; Lee & #39; )

    When we use the generated SQL code of jena/joseki, we are able to get the right result if we execute the query even in SQLDeveloper. To use the variable binding is "Lee" (the binding variable is the price included). This will give you a correct result in withdrawal.

    Kind regards

    Max

    Hi Max,.

    In the area of the UEBV, you must put "Lee" encoded in URL string

    Please, try the following and see if it helps.

    % 22Lee % 22

    Thank you

    Zhe Wu

  • Convert SQL to take advantage of the Bind Variables

    Hi all

    Is it possible to convert the SQL below so I can enjoy variable Bind?  It's just my personal way of followed by the name of the script that I use on a daily basis... the file is passed to a point that its about 2K lines long, and whenever I run this specific file to get a script name, it creates a new SQL in the database pool shared... I tried to change this option to use bind variables , but it doesn't seem to work properly and I wanted what suggestion of the community...

    ACCEPT script_name_like prompt 'ENTER SCRIPT NAME OR HIT ENTER TO GET ALL SCRIPT NAME OR PUT PART OF THE SCRIPT NAME : ' 
    WITH help_script AS
    ( SELECT 'top_seg_tab_obj_ash'                    AS Script_Name,
                        'top segment by tot wait time' AS Description,
                        '# of mins to go back'            AS INPUT
       FROM dual  
      UNION ALL SELECT 'v$_tab'                    AS Script_Name,
                        'shows list v$ views' AS Description,
                        'view name like'            AS INPUT
       FROM dual
      UNION ALL SELECT 'dba_tab'                    AS Script_Name,
                        'shows list dba views' AS Description,
                        'view name like'            AS INPUT
       FROM dual
      UNION ALL SELECT 'nls_params'                    AS Script_Name,
                        'shows list of current NLS setting for DB/INST/SESS' AS Description,
                        'no Input Needed'            AS INPUT )
    SELECT upper(script_name) AS "MY SCRIPT NAME",
           upper(description) AS description,
           upper(INPUT) AS INPUT
    FROM help_script
    WHERE script_name LIKE nvl('%&script_name_like%', script_name) ;
    

    Hello

    user13454469 wrote:

    Hi all

    Is it possible to convert the SQL below so I can enjoy variable Bind?  It's just my personal way of followed by the name of the script that I use on a daily basis... the file is passed to a point that its about 2K lines long, and whenever I run this specific file to get a script name, it creates a new SQL in the database pool shared... I tried to change this option to use bind variables , but it doesn't seem to work properly and I wanted what suggestion of the community...

    1. ACCEPT script_name_like invites ' ENTER NAME or HIT ENTER to GET ALL THE SCRIPT NAME or PART OF THE SCRIPT the SCRIPT NAME: '
    2. WITH help_script AS
    3. (SELECT "top_seg_tab_obj_ash" AS Script_Name,
    4. "upper segment by tot queue time" AS Description,.
    5. "# of minutes to go back" AS INPUT
    6. OF the double
    7. UNION ALL SELECT ' v$ _tab "AS Script_Name,.
    8. "Show list views$ v ' AS Description,.
    9. 'show the name as' AS ENTRY
    10. OF the double
    11. UNION ALL SELECT 'dba_tab' AS Script_Name,
    12. "Show list views dba" AS Description,.
    13. 'show the name as' AS ENTRY
    14. OF the double
    15. UNION ALL SELECT 'nls_params' AS Script_Name,
    16. 'displays the list of current NLS parameter for DB/INST/SESS' AS Description,.
    17. ("No input is necessary" IN ENTRY)
    18. SELECT upper (script_name) AS "MY SCRIPT NAME",
    19. Upper (Description) as a description,
    20. Upper (Input) AS INPUT
    21. OF help_script
    22. WHERE script_name AS nvl (script_name ' % & script_name_like %',);)

    The WHERE clause (last line) of is the only place where you are using the proxy & script_name_like?  If so:

    -ACCEPT command is exactly the same as before

    ACCEPT script_name_like invites ' ENTER NAME or HIT ENTER to GET ALL THE SCRIPT NAME or PART OF THE SCRIPT the SCRIPT NAME: '

    VARIABLE script_name_like_b VARCHAR2 (30)

    EXEC: script_name_like_b: = '% & script_name_like;

    WITH the help _script AS

    ...

    WHERE script_name AS NVL (: script_name_like_b, script_name);

  • Oracle.ManagedDataAccess gives ORA-01006 if there is bind variables in the comments, but only on the lines.

    When I go from ODP.NET to the ODP.NET managed some of my questions begins to throw errors missing bind variable.

    I reproduced with a simple example that uses a variable called liaison: unitName

    It's the example SQL:

    SELECT

    : unitName

    Of

    DOUBLE

    Now, if I add a comment at the beginning of the SQL like this:

    -Text with: unitName

    SELECT

    : unitName

    Of

    DOUBLE

    It works, but if I have a variable binding in a comment that is located on a number of the 'same' line, I get ORA-01006:

    This causes the error:

    -First line comment

    -Text with: unitName

    SELECT

    : unitName

    Of

    DOUBLE

    Kind regards

    -Tommy

    I was able to reproduce this problem. I filed Bug 19433348 on your behalf.

    The circumstances in which the bug occurs are fairly easy to get around.

    (1) remove the colon in the second commented line.

    (2) add a space between the '\n' and ' - '.

    If you are one of those things, you won't encounter the bug behavior.

  • on the ora-01006: there is no bind variable

    Hi all of you, I have this dynamic sql code:

    DECLARE

    CLOB v_query;

    number of CPT;

    Start

    v_query: ='

    SELECT

    County (TBA. ANT_ID)

    Of

    ...

    WHERE TBA. ANT_FUT_ID = TFT. FUT_ID

    AND TBA. ANT_KATEGORIE_CODE_ID = TAKCL. ANT_KATEGORIE_CODE_ID (+)

    AND TBA. ANT_KFZ_REIHEN_ID = TKR. KFZ_REIHEN_ID (+)

    AND TBA. ANT_ID = F1. ANT_ANT_ID (+)

    AND TBA. ANT_ID = F2. ANT_ANT_ID (+)

    AND TBA. ANT_ID = F3. ANT_ANT_ID (+)

    AND TBA. ANT_ID = ERS.ers_bdk (+)

    AND TBA. ANT_ID = F1_2.ANT_ANT_ID (+)

    AND TBA. ANT_ID = F2_3.ANT_ANT_ID (+)

    AND TBA. ANT_ID = UPM. MFU_ANT_ID (+)

    AND UPM. MFU_NIETGEOMETRIE_ID = NG. NG_ID (+)

    AND UPM. MFU_MATRIZEN_BEICHNUNG_ID = MZB. MZB_ID (+)

    --------------------

    -Suchkriterien: -.

    --------------------

    -Creator

    AND DECODE (ERS.ers_id, NULL, '%', ERS.ers_name) AS DECODE (": 1", "%", "') |" ' || :1 ||''''|| DECODE('':1'',''%'',''')

    -Fahrzeug

    AND DECODE (TKR.NAME, NULL, '%', TKR.NAME) AS DECODE (": 2", "%", "') |" ' || :2 ||''''|| DECODE('':2'',''%'',''')

    -BDK

    AND DECODE (fuege_db.bdk_nummer (TBA. ANT_ID, "."), NULL, "PERCENT",

    fuege_db.bdk_nummer (TBA. ANT_ID, ".") ) LIKE '%'. :3||'' %''

    -Technology

    AND TBA. ANT_FUT_ID AS DECODE (": 4%","","') |" ' || :4 ||''''|| DECODE('':4'',''%'',''')

    -Art

    AND ((TBA. ANT_WFP_ID is null and 1 = DECODE('':5'',NULL,1,1,1)) ou (TBA.)) ANT_WFP_ID is not null and 2 = DECODE (": 5 cm, 2,2,2)))

    -ADV

    AND TBA. ANT_VTA = decode (cm: 6 cm, 1.1, TBA.) ANT_VTA) ';

    run immediately v_query

    in USING cpt

    "Dominik Hussmann."

    "AU736_Q7_SUV,"

    '' ,

    "WPS Stahl."

    '',

    '0' ;

    end;

    In execution, I have this error: ora-01006: bind variable does not exist, after analysis, I found that the problem is with the settings: 5 and: 6, I do not understand that they have the same syntax

    as variables bind 1,2,3 and 4.

    Than you for any suggestion.

    I hope that you realize that there are 13 variable bind in your sql, not 6?

    Variables are related by mail. You cannot use the same variable to link twice, they will be 2 separate bind variable.

    For example, you use: 1 three times, so you must provide three arguments, in this case, three times the same value.

  • Refcursor bind variables

    Hi all

    I have a variable refcursor, to which I will assign running queries.

    All are defined (union) queries, with 5 or 6 selects the union, each select returns the same variable where clause. Value of the variable will be known at run time.

    For example: (just an example)

    {code}

    Start

    v_sql: = ' select col1, col2

    of the Department

    where dept_no =: 1

    Union

    Select col1, col2

    of eur_dept

    where dept_no =: 1

    Union

    Select col1, col2

    of us_dept

    where dept_no =: 1 ';

    Open the v_ref_cur for v_sql using 20, 20, 20;

    -rest of the logic

    ------------

    -----------------

    end;

    {code}

    Question is how to avoid the bind variable value repeat (in the open statement). Is there a way I can mention value 20 only once when the cursor is opened.

    Thank you!

    DS says:

    Question is how to avoid the bind variable value repeat (in the open statement). Is there a way I can mention value 20 only once when the cursor is opened.

    Yes - can be done using a dynamic anonymous block to create the refcursor (containing the SQL text), as oppose to the creation of the refcursor directly from the SQL text.

    Not an approach I consider myself - unless there is absolutely no better way to address this particular issue.

    SQL > var refcursor c.

    SQL >

    SQL > declare

    News 2 sys_refcursor;

    3. start

    4 immediate execution

    5 ' declare

    6 varchar2 (4000) var1: =: 1;  -/ / simple definition var - used several times

    7. start

    open 8: news for

    9 select * from emp where mgr = var1

    10 the union all the

    11. Select * from emp where empno = var1;

    12 end; »

    13 using 7698-past the variable once

    14 in the news; -getting refcursor as answer

    15

    16: c: = cur;

    end 17;

    18.

    PL/SQL procedure successfully completed.

    SQL >

    SQL > print c

    EMPNO, ENAME, JOB HIREDATE DEPTNO COMM SAL MGR

    ---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------

    7499 ALLEN SALESMAN 7698 1981/02/20 00:00:00 1600 300 30

    7521 WARD SALESMAN 7698 1981/02/22 00:00:00 1250 500 30

    7654 MARTIN SALESMAN 7698 1981/09/28 00:00:00 1250 1400 30

    7844 TURNER SALESMAN 7698 1981-09-08 00:00:00 1500 0 30

    7900 JAMES CLERK 7698 1981/12/03 00:00:00 950 30

    7698 BLAKE MANAGER 7839 1981/05/01 00:00:00 2850 30

    6 selected lines.

    SQL >

  • bind variables

    Hello

    If I run this query from my sql * more customer, what is the difference between substitution and the bind variable then?

    Select * from emp where empno = & x;

    Select * from emp where empno =: x;


    In both cases, my request that will be sent to the server for execution will be completed (with no reserved space).


    The only difference I can think is that we cannot use bind variable instead of table_names & the names of column, but we can use substitution variables. As shown below


    Select * from: var where empno =:-this will not work when they are under values dynamically


    Select * from & var where empno = & y - it works.

    So what else is the difference between substitution and the bind variable then?

    Thank you

    When you use a variable substitiution in sqlplus or any other client that supports, the client interprets the value of the variable and puts it into the sql statement.  So, if you have:

    Select * from emp where emp_id = & n

    The customer gets the value you supply and replaces the variable substitution with the value you provide, thus, if you enter 10 the query that the sql engine sees is actually:

    Select * from emp where emp_id = 10

    This is why you must put quotes around a variable substitution when using it as a string in a projection or a predicate.  In other words, if you want to query by last_name with a substitution variable, you would do something like:

    Select * from emp where last_name = '& ln '.

    When you use a link as variable:

    Select * from emp where emp_id =: n

    the client passes the sql statement, exactly as you wrote it and at the same time he says also, moreover, the value of: n is 10.  If you then change the value of: n 20 the customer always going the same exact sql statement, but this time, says the value of: n is 20.

    As others have pointed out, with a substitution variable each sql statement with a new value for the variable is a brand new, never seen before trial and must be hard to be analyzed by the SQL engine.  Whenever you use a new value of a variable to bind the SQL remains the same, so the SQL engine can avoid the hard analysis (expensive).

    John

  • See criteria and bind variables

    Greetings experts,

    I use JDev, version: 11.1.2.3.0

    Recently, I came across this situation. I created a variable binding (in VO), which is used inside a criterion for the VO even. This criterion to display is called within a method that is declared within a class of java of implementation of AppModule (which is exposed on the Client Instance), and through a managed bean I supply the parameter required to initialize the variable binding (and then get the results). This works fine, and the page that uses the domain controller for this appmodule runs without error.

    The point is that I have the same VO, used inside an another appModule (and another page uses, it's DC). I need to use this variable binding in this case, but if I click edit on this VO second, inside the second presentation of appModule interface, I can see that the criteria for the view, is in the "Available" tab, but in the section 'Setting bind' it shows the binding variable said first.

    I am as a matter of fact, receiving and error on this second page if I do some operations, saying this:

    Caused by: java.sql.SQLException: try to set a parameter name that does not intervene in the SQL: partyNum

    at oracle.jdbc.driver.OraclePreparedStatement.setNullAtName(OraclePreparedStatement.java:5384)

    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setNullAtName(OraclePreparedStatementWrapper.java:1451)

    at oracle.jbo.server.OracleSQLBuilderImpl.bindParamValue(OracleSQLBuilderImpl.java:4695)

    at oracle.jbo.server.BaseSQLBuilderImpl.bindParametersForStmt(BaseSQLBuilderImpl.java:3673)

    at oracle.jbo.server.ViewObjectImpl.bindParametersForCollection(ViewObjectImpl.java:21459)

    at oracle.jbo.server.QueryCollection.buildResultSet(QueryCollection.java:1197)

    SQL error in the preparation of the statement.  Instruction: SELECT PartiesContracts.CONTRACT_IDCONTRACT, PartiesContracts.PARTY_TYPE, PartiesContracts.PARTY_NUM, PartiesContracts.ROLE PARTIES_CONTRACTS PartiesContracts WHERE PartiesContracts.CONTRACT_IDCONTRACT =: Bind_Idcontract

    (The binding variable is called, partyNum)

    My question is, can I do to avoid using this variable to link on the second page of appModule only? It seems to be called always regardless the fact if I call the appropriate support bean method that triggers the initialization process.

    Thank you for your time.

    Have you defined the binding variable 'partyNum' as requires it? In this case, you need to specify every time. You can set the variable as not mandatory and it might work.

    The solution would be to set another VO with the same base, without the "partyNum" bind variable and VC and use in the other AM.

    Timo

  • How to pass a list as a bind variable in SQL Developer?

    How can I pass a list as a bind variable in SQL Developer?

    The following query in SQL Developer so work I put ": prmRegionID = 2.

    SELECT COUNTRY_ID,
    COUNTRY_NAME
    OF HUMAN RESOURCES. COUNTRY
    WHERE IN REGION_ID (: prmRegionID);

    The problem is that I can't find how to set ": prmRegionID = 2, 3.

    I know that I can replace ": prmRegionID" by a proxy '& prmRegionID '. The above query will work well with"& prmRegionID = 2" and with "& prmRegionID = 2, 3". "

    But with this solution, I lost all the benefit of the use of bound variables (analysis hard against soft parse, possibility of SQL injection, etc.).

    I'm learning how to do this in SQL, as well as the use of UDT in this thread: How to move a list as a bind variable?

    But with this solution, I've lost nice SQL Developer user interface. In SQL developer, it is easy to test a query using the standard binding variable. When we start the application, a pop up asking for a value of the variable binding.

    With the UDT, the interface request always variable binding standard. You have an idea on how I can get a variable string binding (such as 1, 2, 10) in a set of NUMBER or VARCHAR2? This way I would be able to launch a standard query in SQL Developer to test my application.


    Can someone tell me what is the best approach to this?

    Thank you in advance,


    MB

    Hi Blais,

    Thank you for trying the SQL and PL/SQL instance before coming here - it was definitely the right approach, and you've got some very good suggestions there. Your needs for a invite only bind to the value in the clause list, I think I have a possible solution. I'll introduce you to a list of characters, so you'll have to tweak it for other types of data. First, add the following to your schema:

    create or replace
    TYPE bind_tab_typ AS TABLE OF VARCHAR2(4000);
    
    create or replace
    FUNCTION comma_to_table(iv_raw IN VARCHAR2)
    RETURN bind_tab_typ
    PIPELINED
    IS
       ltab_lname dbms_utility.lname_array;
       ln_len     BINARY_INTEGER;
    BEGIN
       dbms_utility.comma_to_table(list   => iv_raw
                                  ,tablen => ln_len
                                  ,tab    => ltab_lname);
       FOR i IN 1 .. ln_len LOOP
          PIPE ROW (ltab_lname(i));
       END LOOP;
    END;
    

    Now you can write a query, say for scott.dept, as follows, and have executed statement ask the value list in the clause as a single binding variable:

    select *
    from dept
    where dname in (
      select * from table( comma_to_table( :BNDS ))
    );
    

    When you are prompted, provide the list of values separated by a single comma without any extra spaces.

    I don't know if the Varchar2 (4000) really needs to be which is great. I use it because that's what dbms_utility.lname_array uses.

    Kind regards
    Gary
    SQL development team

  • Performance tests: bind variables

    When you write a SQL for the application, I want to do some performance testing of SQL before providing to JAVA developers. I understand that I need to test using bind variables, can someone guide me how do? What are the best tools out there to achieve? Please provide some guidance. Thank you!

    Rinne says:
    I read more about bind variable and I can test the use of bind variables. I understand that testing SQL using bind variables is a closer representation of the real world. Even when queries have large tables, the performance would be similar if I run the query using literals twice (to avoid hard analysis) compared to tests with bind variables? I am trying to understand more thoroughly the need for tests with bind variables. Why we take more time than the other? Thank you!

    The main thing is that the opimizer will / can do if bind variables different optimization techniques are used or not.
    There are two contradictory effects its regarding the binding settings.

    Effect 1: Reuse of cursor
    If the same is done again and again and again. Maybe different sessions. Then using binding settings is essential. Why? Because the same cursor can be reused, which saves a lot of time for analysis. This occurs mainly in OLTP systems. The idea behind this is that to do the same action, just for a different ID (ID in order for example) will result in an identical implementation plan.

    The result: Faster analysis time and less consumption of memory, because the same cursor can be resused between different sessions.

    Effect 2: Correct assumptions

    According to a filter expression, some using the value of the OBC will make an assumption based on statistical data the number of rows is returned because of this expression and the value.
    Speculation between a literal value and a bound value may be different. In many cases exist technical opimization (bind peeking etc.) to the same literal conjecture binded proposal.

    But there are exceptions, for example a condition such as the following will result in different estimates

    column between 10 and 20
    
    column between :P1 and :P2
    

    There are as well other effects.

    Result: The CBO can make assumptions better if literals. But most of the cases the proposal is identical.

    Conclusion: Literal values are useful if you do large queries where the output size depends strongly on the parameters provided, and where you run that very few of these (OLAP) queries.
    Binding settings are usfull when the same execution (OLTP) need a grand plan number of queries.

Maybe you are looking for