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.

Tags: Database

Similar Questions

  • literal and bind variables

    Hello

    What is the difference between literal and bind variables?
    What happens if I use
    literal variable has.
    variable b.bind

    who is suggested?

    Kind regards
    KKK

    There are two phases of any SQL performance.

    1. analysis (check Oracle this SQL syntax, also generates the implementation PLAN)
    2. execution (the real execution takes place)

    Below, SQL.

    Select * from emp where empno = 1234;

    I used literal in the SQL above.

    For each SQL type similar (average for empno modified value) oracle must analyze the SQL for each performance.

    Select * from emp where empno =: v_emp_no;

    I used the bind variable in the SQL above.

    In the oracle SQL above needs to analyze once, next time ehen this SQl will be executde with the value of the bound different variable, oracle will use the old execution PLAN and analysis will be not not happed. It will be a little fast.

    Also variable binding instead of literal use reduced use shared pool.

    HTH

    Best regards
    oratest

  • 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

  • Immediate execution, to update and bind Variables

    I can't EXECUTE IMMEDIATE to work with an update statement when trying to link the name of the table. Consider the following example:
    create table gr_test(
      n Number);
      
    insert into gr_test (n) values(1);
    The anonymous block under works:
    declare
      update_statement Varchar2(2000);
    begin
      update_statement := '
      update gr_test
         set n = 2';
    
      execute immediate update_statement;
    end;
    but not
    declare
      update_statement Varchar2(2000);
    begin
      update_statement := '
      update :table_name
         set n = 2';
         
      execute immediate update_statement
        using 'gr_test';
    end;
    It gives ORA-00903 - invalid table name.

    You can not link the names of tables/columns using the clause Bind Variables (USING).

    You need to add to the dynamic SQL.

    Something this way:

     declare
       update_statement Varchar2(2000);
       v_table_name        varchar2(30);
     begin
       v_table_name = 'GR_TEST';
       update_statement := '
       update ' || v_table_name || '
          set n = 2';
    
       execute immediate update_statement;
     end;
     
    

    For more information about the Execute Immediate, please read execute immediate statement.
    For Dynamics, reading SQL statements dynamic SQL Oracle 11 g.

  • Ask about bind variables and LOVs

    Hello
    I'm new to ADF. Last day, I learned about LOVS, see criteria and bind variables. Now, I tried to develop a sample application. I created a few EOs, village and an AM.
    I also defined a view criteria which takes as a parameter a variable binding and rule the condition when running. Then, I created a group of query based on my view criteria. In this query Panel, when I enter the name of a student in a box (which is related to the binding variable that I guess), the student information is displayed in a table. Now, instead of an entry box, I want a list of choices based on a LOV-driven model that will contain all the names of students available. Is this possible in ADF 11 g?

    Thanks in advance

    You must open the VO, you use, go to the view whole section and in the view whole section go in the attributes section.

    In attributes, select the attribute by which you are to the search or make your operation, click on the button add to the list of values: the name of the attribute

    Select the vo object to fill the value.

    You will get the data in the variable binding, that you created in the view criteria.

    Reporter, you can follow the bolg

    http://saumoinak.blogspot.com/2011/02/showing-data-based-on-list-of-values.html

  • printing problem in pdf and csv using bind variables

    Hello

    I created a simple sql statement using a query and bind variables. I noticed when I remove the bind variables and hardcode the values that the CSV/PDF links work. When I handed the return variables in the query, the WB shows "no data found" and pdf shows only the column header.

    If anyone can help me, I would be very happy!


    Thank you
    Ayed P.

    Hello

    How are set the bind variable? If there are topics evaluated by default on the elements of the page, so is not necessarily enough to ensure that the exports are their values. To set values, I tend to use calculations, conditional that the element is null, what works "Before Header". In this way, the value is stored in the session and is available for export. I think the defaults to be those that are defined when the page is submitted and are not available until now.

    Andy

  • Ensure this soft analysis the use of Bind variables

    Hi Experts,

    I have a request when the query is prepared dynamically in Java code and if I take the query and run it from SQL Navigator, it takes a long time to prepare the statement and then execute it quickly. I think we can use dynamic SQL statements and bind variable to improve performance here. However, I tried to do a PDS to check my understanding. I created 2 procedures

    1. mode of operation
    CREATE OR REPLACE PROCEDURE sp_static
    (id IN NUMBER, 
     name in VARCHAR2)
    IS 
    TYPE r_curs_type is REF CURSOR;
    C1 r_curs_type;
    BEGIN
    
    OPEN C1
    FOR
    SELECT * FROM TABLE WHERE columname = id
    
    CLOSE C1;
    
    END;
    2. mode of operation
    CREATE PROCEDURE sp_dyanmic
    (id IN NUMBER, 
     name in VARCHAR2)
    IS 
    TYPE r_curs_type is REF CURSOR;
    C1 r_curs_type;
    BEGIN
    
    OPEN C1 FOR 'SELECT * FROM TABLE WHERE columnanme = :U1' 
    USING ID;
    
    CLOSE C1;
    END;
    To my amazement, there is no difference in the duration of execution of these procedures when I ran the with multiple entries.

    Please note-
    1. I have not access to trace files :-(
    2. I want to just make sure there will be improved performance before starting the real work, given that some efforts provided by moving the logic of all its activities inside and the use of bind variables.

    If you can suggest a strategy to ensure performance gains, it will be extremely useful...

    Thanks in advance!
    Concerning

    Hello

    (1) it's true, procedure 1 also uses a variable binding
    (2) you seem to be confused about the very basic concepts here

    Dynamic SQL is something like this:

    create or replace FUNCTION f (l_table_name VARCHAR2) RETURN NUMBER
    IS
      l_result NUMBER;
    BEGIN
      EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || l_table_name  INTO l_result;
      return l_result;
    END;
    

    In this example, since you do not know the name of the table to the execution table, everything you can
    is dynamic SQL. As you can see, neither of your two procedures is like that.

    Dynamic SQL is used when you do not know what columns you want to select, or who
    etc. to the execution table. You can also use dynamic SQL statements to force analysis. You can not use
    to avoid parsing, binding or not binding.

    Best regards
    Nikolai

  • The use of bind variables in dynamic query created for Ref Cursor

    Hello

    I'm in a situation where there is a Ref cursor to which the query is built execution based on a loop. This is why the number of links would be known until the program runs.
    The application is currently using literals instead of bind variables.

    code snippet of the above is
    strSql: = "select * from emp where 1 = 1 and ().

    loop cursor1
    If cond is true then
    strSql = strSql | "ename = ' |" Cursor1.ColumnName;
    end loop;

    Open cursor2 for strSql;

    How to use links in the example above.

    sb92075 wrote:

    user13019948 wrote:
    Hello

    Here is the code I have my trying to change literal-based link to the base.

    What do you mean by "based bind?

    who, what, how determines the values to be 'bound '?

    He's referring to the coding style. He is currently using concatenated literal, and the goal is to change it to use the bindings.

    If I understand this it is known as method 4 dynamic SQL and requires DBMS_SQL. There are examples autour but they vary according to the type of statement being generated - SELECT statements require column lists to be parsed, unlike the INSERT/UPDATE/DELETE.

    This came up recently on my current project and I hit a demo. Here a table of names and values accepted procedure and had to build these in a single WHERE clause along the lines of

    AND t_names(i) = t_values(i)
    

    for an undetermined number of elements in the array. For this demonstration, I used a table that we called "attribute" (don't ask) which has columns including 'attribute_id' and 'name', and I need to build a query along the lines of

    select description from attribute where attribute_id = :b1 and name = :b2
    

    by the way '1012' and 'ISIN' respectively. (I use a table better and after a CREATE statement for her but I have to rush right now, sorry).

    declare
       k_sql_base        constant varchar2(500) := 'select description from attribute';
    
       t_names           constant varchar2_t := varchar2_t('attribute_id',  'name');
       t_values          constant varchar2_t := varchar2_t('1012',          'ISIN');
    
       l_sql             varchar2(500) := k_sql_base;
       l_rows_fetched    integer := 0;
       l_value           varchar2(4000);
    
       l_cursor_handle   integer;
    
    begin
       -- Construct the SQL statement with column names and bind variables e.g.
       -- 'select description from mars.attribute where attribute_id = :b1 and name = :b2'
       for i in t_names.first .. t_names.last loop
          l_sql := l_sql ||
             case i
                when t_names.first then ' where ' else ' and '
             end ||
             t_names(i) || ' = :b' || i;
       end loop;
    
       dbms_output.put_line('SQL statment = ' || l_sql); 
    
       -- Parse the statement we built above (the remaining steps require a parsed cursor):
       l_cursor_handle := dbms_sql.open_cursor;
       dbms_sql.parse(l_cursor_handle, l_sql, dbms_sql.native);
    
       -- Associate the 1st column of output with variable l_value - required for SELECT statements:
       -- (actually the 3rd param here 'column' seems to be only used to get a datatype, in this case we want a string -
       -- dbms_sql.column_value actually extracts the value into a specified variable, which can be different.
       -- All examples in the documentation pass a local variable without further comment, so not entirely clear what this does other than set the output datatype.)
       dbms_sql.define_column(l_cursor_handle, 1, l_value, 4000);
    
       -- Now go through values array binding actual values to :bn variables in the cursor (similar to USING clause of EXECUTE IMMEDIATE)
       for i in t_values.first .. t_values.last loop
          dbms_sql.bind_variable(l_cursor_handle, ':b'||i, t_values(i));
          dbms_output.put_line('Bound :b'||i || ' as ' || t_values(i));
       end loop;
    
       -- Open the cursor and fetch the result (no loop here because we are expecting a single-row result):
       l_rows_fetched := dbms_sql.execute_and_fetch(l_cursor_handle);
    
       -- 'Returns value of the cursor element for a given position in a cursor'
       -- Copy the value of column 1 to variable l_value (has to match
       -- dbms_sql.column_value(l_cursor_handle, 1, l_value);
       dbms_sql.column_value(l_cursor_handle, 1, l_value);
    
       dbms_output.put_line('Result = ''' || l_value || '''');
    
       dbms_sql.close_cursor(l_cursor_handle);
    end;
    

    Hope that helps...

  • A query on bind variables

    Hello

    I have a procedure that takes the deptno parameter and inserts that records departments of the table emp for the new table.

    This code does not exist in a real system. I was trying to understand that the advantage of linking variable.i he wrote in different ways as below
    Create table emp3 as select * from emp where 1=2;
    
    create or replace procedure test1 (p_deptno in number)as 
    begin
     execute immediate 'insert into emp3
                                   select *
                                   from emp
                                   where deptno=:1'
                                   using p_deptno;
    end;
    The works fine.i code above writes the following much too.

    create or replace procedure test2 (p_deptno in number)as 
    begin
     insert into emp3
          select *
          from emp
          where deptno=p_deptno;
    end;
    the first no matter what performance benefit over the second one that is the right way to do it in a real-world system?
    . I could not do a comparison of performance because I don't have access to a currently oracle instance and did it in workshop SQL that comes with Apex.My apology for this...

    Kind regards
    CKLP

    Published by: CKLP on August 29, 2011 03:21

    CKLP wrote:

    the first no matter what performance benefit over the second one that is the right way to do it in a real-world system?

    Not really. Do not forget that all interpreted SQLs winds up as sliders to the sharing of the database Pool.

    If a cursor exists already for a SQL statement, SQL will reuse this slider existing (soft parser). So in a SQL engine perspective, there is no different between the two methods. These statements will be btw generate the same cursor SQL - code SQL of base and bind variable positions are identical.

    From a PL/SQL's point of view, there is a huge difference.

    The first option may be a little slower. Why? There he uses the immediate execution interface which is not as optimized as the implicit cursor to the PL/SQL interface. You use a "heavier" SQL interface in PL/SQL which results in more work for the PL/SQL engine.

    The second option is compiled in an implicit cursor. The SQL code is known, controlled and checked, and compiled PL/SQL code deals with a known SQL statement. Unlike the first option.

    The second option also means that your code will not fail (because SQL syntax errors, etc.) currently running. If this static SQL statement in your code is no longer valid (due to a table being deleted, used column removed, etc.), then your code becomes invalid. With the first option, the code remains valid - and when it is executed, it will throw an exception that the (dynamic) SQL cannot be analyzed and that it is not valid.

    The first option also introduces the spectrum of a SQL injection. Let's say that there is a way to cause a buffer overflow exploit in the database call that executes this procedure. The SQL itself is a string, it is an easy attack vector as the overflow needs that data of type string to inject executable code - as opposed to the p-code or machine code. (an unlikely scenario, but the basic principle of security remains true)

    Dynamic SQL is unnecessary for 99% of the time in PL/SQL. And 99% of the time, with the help of the dynamic SQL is for the wrong reasons, or ignorance or both.

  • EO base extension VO with bind variables and display - How To link

    Hello

    I extended an APInvDistAllVO view object by adding two fields which are functions. Basically, in the invoice approval screen, I want to add two fields where the distribution of the invoice is shown.

    The SQL contained in jdeveloper when you extend the VO object is different from the query, what I see in the invoice approval page by clicking on the APInvDistAllVO link. There are two bind variable: 1 = invoice_id and: 2 = line_number being added dynamically. After the extension of the view object, the invoice distribution line is displayed as no record found.

    In my opinion, it is due to not having bind variables does not correct parameters being passed, and under this point of view object is an object depending on the invoice header record. There is a link to the original View object as well. Will be very grateful if someone can provide the way forward in dealing with this situation.

    Rgds Fahad

    Hi AJ

    He worked after changing the style of bind.

    Thank you very much.

    Rgds

    Fahad

  • Bind variables and dates

    I am writing a process to delete records based on dates.

    Here is the chart:

    Column name Data type Nullable Default Primary key
    IDNUMBERNO.-1
    CT_NAMEVARCHAR2 (100)Yes--
    CT_CATEGORYVARCHAR2 (100)Yes--
    BASE_PTSNUMBERYes--
    PROD_PTSNUMBERYes--
    REF_PTSNUMBERYes--
    START_DATEDATEYes--
    END_DATEDATEYes--
    CREATED_ONDATEYes--
    CREATED_BYVARCHAR2 (50)Yes--
    UPDATED_ONDATEYes--
    UPDATED_BYVARCHAR2 (50)Yes--

    start_date and end_date are the fields of date key.

    The query will remove the dates with specific start and end dates.  The question I have, is that I get a ORA-01858: a non-digit character was found here where was waiting for a digital error while the query is running.

    remove from ct_point_values

    where start_date =: P4_START_DATE_V

    and end_date =: P4_END_DATE_V

    If I run the query in the sql window, no problem:

    remove from ct_point_values

    where start_date =' 01 / 01/2014 '

    and end_date = 31 December 2014"

    Find the query with the works of values hard-coded.  Links to fail.  I tried casting and to_char to_date variations with no luck.

    One thing that I notice, is that when I go to enter my bind variables in the sql workshop, the fields are pre-populated with this:

    1 & amp; #x2F 1 & amp; #x2F; 2014

    12 & amp; #x2F 31 & amp; #x2F; 2014

    01/01/2014 and 31/12/2014.  I found that the only element relates to this suggests that this is a possible bug:

    SQL Bind Variables workshop - Date issues

    Any thoughts on how to address this issue, or is it really a bug?

    I run on Apex 4.2, 11g.

    Thank you!

    Hello

    I guess that these dates come from elements on the page to which the user can select a range of dates.

    These fields have a custom format mask?

    What seems to be the case for me, is that these fields have an explicit format mask (for example: DD/MM/YYYY) but the default database/session format mask is something different (e.g. DD-MON-YYYY).

    I suppose also that the issue in the SQL workshop isn't something related.

  • 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.

  • Link to ' effective use of bind variables, cursor_sharing and related ' KO

    If I try to access to "the effective use of the bind variables, cursor_sharing and parameters related cursor" doc with link http://www.oracle.com/technetwork/database/features/performance/whitepapers-098560.html http://www.oracle.com/technology/deploy/performance/pdf/cursor.pdf I get

    >
    We're sorry, the page you requested was not found.
    We recorded this error (404) to help us solve the problem.
    You can try again using one of the tools below.
    Back to previous Page
    Site map
    Index of products
    To find your page, try our search function.
    Refine your search

    This PDF file does not exist if the link has been deleted.

  • bind variables and dynamic sql

    Hi all

    Here's my situation:

    I have a query with 2 bind variable: the FROM clause also uses a variable binding!

    PROCEDURE describe_columns(p_curr_tablename VARCHAR(50), p_curr_intentseq NUMBER)
       IS
          l_cur     INTEGER;
          l_query   VARCHAR (100);
       BEGIN
          l_query :=
             'select * from :table_name where ibmsnap_intentseq = :sequencenr';
          l_cur := DBMS_SQL.OPEN_CURSOR;
          DBMS_OUTPUT.PUT_LINE (p_curr_tablename);
          DBMS_OUTPUT.PUT_LINE (p_curr_intentseq);
          DBMS_OUTPUT.PUT_LINE (l_query);
          DBMS_SQL.PARSE (l_cur, l_query, DBMS_SQL.V7);
          DBMS_SQL.bind_variable (l_cur, ':table_name', p_curr_tablename);
          DBMS_SQL.bind_variable (l_cur, ':sequencenr', p_curr_intentseq);
          DBMS_SQL.DESCRIBE_COLUMNS (l_cur, g_count, g_desc_tab);
          DBMS_SQL.CLOSE_CURSOR (l_cur);
       EXCEPTION
          WHEN OTHERS
          THEN
             DBMS_OUTPUT.put_line ('DF-EXCEPTION: ' || SQLERRM);
             DBMS_OUTPUT.put_line (
                'DF-EXCEPTION: ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
             );
    
             IF DBMS_SQL.IS_OPEN (l_cur)
             THEN
                DBMS_SQL.CLOSE_CURSOR (l_cur);
             END IF;
       --         RAISE;
       END;
    and the output is:
    CD_B136V4_NEW
    16
     select * from :table_name where ibmsnap_intentseq = :intentseq
    DF-EXCEPTION: ORA-00903: invalid table name
    DF-EXCEPTION: ORA-06512: in "SYS.DBMS_SYS_SQL", line 906
    So is the problem that I want to use a variable binding for the name of the table?

    I'd appreciate any help!
    Thank you!

    http://asktom.Oracle.com/pls/asktom/f?p=100:11:0:P11_QUESTION_ID:227413938857

    Identifiers cannot be used as variable bind - never. Identifiers must be "hard-coded".
    in the query.

    I can't put in a link for "emp" variable because I can't use a string
    constant for emp.

    The reason is quite simple - a bind variable query is parsed and optimized once
    variables are evaluated before linking. If I could code:

    Select * from: bind_x

    the optimzer would not have an idea of what will come with, security (access rights)
    could be evaluated and so on. We could not develop a plan for this query - not
    enough information. Therefore, no variable bind for identifiers.

  • bind variables and v$ sqlarea

    Hello

    How to distinguish the variable bind to static expression
    in v$ sqlarea? Is this possible?
    Please explain

    Best regards
    Paul

    Hello

    You acknowledge that bind variable by ':' in front, you cannot merge with literals.

    Best regards
    Nikolai

Maybe you are looking for

  • Cannot answer security questions required to reset PW

    It's so crazy.  I was told that my account could be hacked, so I should update my password.  I go to the website of password and it ask me two questions of car I never responded and he tells me that my answers are wrong.  What I do cause I can't rese

  • Part of the image appears in the scanned image

    I have an officejet 6600 all-in-one printer.  Lately, whenever I try to scan the image is cut off.  Only a small part of the document appears in the final image.  The content is visible on the scanned image is in the lower right of the scanning space

  • Remove "shortcuts" in the Office

    I downloaded a pix data folder and the film from a security camera on my desk.  He opened and threw up 1200 "shortcuts" on my desktop.  I can delete laboriously one by one in the trash (others fill the Office at the next opening), but is there a way

  • HP 15-d006tu Wifi in Windows 7 64 bit driver

    I followed the instructions posted in this thread http://h30434.www3.hp.com/t5/Notebook-Hardware/which-wifi-card-is-installed-in-hp-15-d006tu-laptop/t... but that did not help because I am still unable to find the driver. I bought this laptop yesterd

  • I can not find Bluetooth driver for my vaio VPCF227FX after OS update to windows8.

    after update to windows 8 I can't find driver Bluetooth for this page http://eSupport.Sony.com/us/p/model-home.pl?MDL=VPCF227FX&template_id=1&Region_ID=1&tab=download#/do... model: VPCF227FX so I wonder if sony will forget that...