Substitution vs bind variable

Hi,
Can you please give me the differences between substitution vs bind variables? I have done many searches and I am lost. Any examples would be great.
Thanks.
-U

Perhaps what is needed is a simple example of both.
h2. Substitution Variables
The clue here is in the name... "substitution". It relates to values being substituted into the code before it is submitted to the database. These substitutions are carried out by the interface being used. In this example we're going to use SQL*Plus as our interface...
So let's take a bit of code with substitution variables:
SQL> ed
Wrote file afiedt.buf
  1  create or replace function myfn return varchar2 is
  2    v_dname varchar2(20);
  3  begin
  4    select dname
  5    into   v_dname
  6    from   dept
  7    where  deptno = &p_deptno;
  8    return v_dname;
  9* end;Now when this code is submitted...
SQL> /SQL*Plus, parses the code itself, and sees the "&" indicating a substitution variable.
SQL*Plus, then prompts for a value for that variable, which we enter...
Enter value for p_deptno: 20
old   7:   where  deptno = &p_deptno;
new   7:   where  deptno = 20;... and it reports back that it has substitution the &p_deptno variable for the value 20, actually shoing us the whole line of code with it's value.
This code is then submitted to the database. So if we look at what the code is, now created on the database we see...
SQL> select dbms_metadata.get_ddl('FUNCTION', 'MYFN', USER) from dual;
DBMS_METADATA.GET_DDL('FUNCTION','MYFN',USER)
CREATE OR REPLACE FUNCTION "SCOTT"."MYFN" return varchar2 is
  v_dname varchar2(20);
begin
  select dname
  into   v_dname
  from   dept
  where  deptno = 20;
  return v_dname;
end;The database itself knows nothing about any substitution variable... it just has some fixed code with the value we supplied, that SQL*Plus substituted when we compiled it.
The only way we can change that value is by recompiling the code again, and substituting a new value for it.
Also, with substitution variables we don't necessarily have to use them just for 'values' (though that it typically what they're used for)... we can use them to substitute any part of the code/text that we are supplying to be compiled.. e.g.
SQL> ed
Wrote file afiedt.buf
  1  create or replace function myfn(x in number, y in number) return number is
  2  begin
  3    return &what_do_you_want_to_return;
  4* end;
SQL> /
Enter value for what_do_you_want_to_return: y*power(x,2)
old   3:   return &what_do_you_want_to_return;
new   3:   return y*power(x,2);
Function created.
SQL> select dbms_metadata.get_ddl('FUNCTION', 'MYFN', USER) from dual;
DBMS_METADATA.GET_DDL('FUNCTION','MYFN',USER)
CREATE OR REPLACE FUNCTION "SCOTT"."MYFN" (x in number, y in number) return number is
begin
  return y*power(x,2);
end;It really does substitute the substitution variable, with whatever text you type.
So, that's substitution variables. In summary they are variables that the user interface detects and prompts for text to substitute into the code before submitting it to the database.
h2. Bind Variables
Bind variables are a completely difference concept to substitution variables.
Bind variables typically relate to SQL queries, and are a placeholder for values within the query. Unlike substitution variables, these are not prompted for when you come to compile the code.
Now there are various ways of supplying bind variables, and I'll use a couple of examples, but there are more (such as binding when creating queries via the DBMS_SQL package etc.)
In the following exaxmple:
SQL> ed
Wrote file afiedt.buf
  1  create or replace function myfn(p_deptno in number) return varchar2 is
  2    v_dname varchar2(20);
  3    v_sql   varchar2(32767);
  4  begin
  5    v_sql := 'select dname from dept where deptno = :1';
  6    execute immediate v_sql into v_dname using p_deptno;
  7    return v_dname;
  8* end;
SQL> /
Function created.The ":1" is the bind variable in the query.
If you examine queries running in the database you will typically see bind variables represented as :1, :2, :3 and so on, though it could be anything preceded by a ":" such as :A, :B, :C, :X, :FRED, :SOMETHING etc.
When the query is passed to the SQL engine (in this case by the EXECUTE IMMEDIATE statement), the query is parsed and optimised and the best execution plan determined. It doesn't need to know what that value is yet to determine the best plan. Then when the query is actually executed, the value that has been bound in (in this case with the USING part of the execute immediate statement) is used within the execution of the query to fetch the required data.
The advantage of using bind variables is that, if the same query is executed multiple times with different values being bound in, then the same execution plan is used because the query itself hasn't actually changed (so no hard parsing and determining the best plan has to be performed, saving time and resources).
Another example of using bind variable is this:
SQL> ed
Wrote file afiedt.buf
  1  create or replace function myfn(p_deptno in number) return varchar2 is
  2    v_dname varchar2(20);
  3  begin
  4    select dname
  5    into   v_dname
  6    from   dept
  7    where deptno = p_deptno;
  8    return v_dname;
  9* end;
SQL> /
Function created.Now, this isn't immediately obvious, but what we have here is the ability of the PL langauge to seamlessly integrate SQL within it (giving us PL/SQL). It looks as though we just have an SQL statement in our code, but in reality, the PL engine parses the query and supplies the query to the SQL engine with a bind variable placeholder for where the PL variable (parameter p_deptno in this case) is within it. So the SQL engine will get a query like...
select dname
from   dept
where  deptno = :1and then the PL engine will handle the binding of the value (p_deptno) into that query when it executes it, as well as dealing with the returning value being put INTO the PL variable v_dname. Again the SQL supplied to the SQL engine can be optimised and re-used by code because it isn't hard coded with values.
So, here, the binding of values is implicit because the PL engine is removing the need for us to have to code them explicitly.
The other advantage of using bind variables is that you don't have to worry about the datatypes.
Often we see people creating code such as this (going back to a similar dynamic SQL example)...
SQL> ed
Wrote file afiedt.buf
  1  create or replace function myfn(p_hiredate in date) return number is
  2    v_empno number;
  3    v_sql   varchar2(32767);
  4  begin
  5    v_sql := 'select empno from emp where hiredate = to_date('||to_char(p_hiredate,'DD/MM/YYYY')||',''DD/MM/YYYY'')';
  6    execute immediate v_sql into v_empno;
  7    return v_empno;
  8* end;
SQL> /
Function created.... where the developer is trying to concatenate in a date or varchar variable with the appropriate single quotes and formatting required to make the SQL make sense. Not only does that prevent the SQL explain plan from being re-used with different values, but it makes the code hard to maintain and get right in the first place (as well as leaving things open to SQL injection)
But, with bind variable, that's not necessary... simply doing...
SQL> ed
Wrote file afiedt.buf
  1  create or replace function myfn(p_hiredate in date) return number is
  2    v_empno number;
  3    v_sql   varchar2(32767);
  4  begin
  5    v_sql := 'select empno from emp where hiredate = :1';
  6    execute immediate v_sql into v_empno using p_hiredate;
  7    return v_empno;
  8* end;
SQL> /
Function created.... is all that is needed.
The SQL engine knows that it is expecting a DATE datatype for the value because of what it's being compared against, and the USING statement is supplying a value of DATE datatype. No messy need to play with date formats or quotes etc. it just simply works. (and the same with other datatypes).
So, that's bind variables. In summary they are placeholders in queries that allow SQL queries to be soft parsed rather than hard parsed when the query is re-used, help prevent SQL injection, and allow for the values to be supplied easily and seamlessly by the issuing code.

Similar Messages

  • Storing the contents of a substitution or bind variable in a PL/SQL var

    Hi,
    I would like to create a substitution or bind variable to store the name of a sequence to use in SQLPlus and then reference this in a PL/SQL procedure and assign the contents of the substitution or bind variable in the PL/SQL variable. Is this possible?
    Regards,
    Sean

    A substitution variable can only be used in an anonyomous PL/SQL block, not a stored procedure. You would pass the sequence name in via an input parameter to that stored proc.
    In an anonymous block though:
    sql>declare
      2    v_seq_name  user_sequences.sequence_name%type;
      3    v_value     number;
      4  begin
      5    v_seq_name := '&seq_name';  -- assign substitution to variable
      6    execute immediate 'select ' || v_seq_name || '.nextval from dual' into v_value;
      7    dbms_output.put_line( v_value );
      8  end;
      9  /
    Enter value for seq_name: SEQ
    old   5:   v_seq_name := '&seq_name';
    new   5:   v_seq_name := 'SEQ';
    24
    PL/SQL procedure successfully completed.

  • How to pass parameter [bind variable or substitution variable] to a view?

    How can I pass a parameter [bind variable or substitution variable] to a view in Oracle?
    Some will tell me that this is not necessary, that I can only pass the parameter when I query the view, but I found some case where this cause performance issue. In long view where I use subquery factoring [WITH], it's necessary to pass the parameter many time through different subqueries and not only to the resulting view.
    In other database (SQL Server, Access), we can pass parameters through query. I can't find how to do that in Oracle. Can some one tell me what is the approach suggest by Oracle on that subject?
    Thank you in advance,
    MB
    What I can do:
    CREATE VIEW "HR"."EMP_NAME" ("FIRST_NAME", "LAST_NAME")
    AS
    SELECT FIRST_NAME, LAST_NAME FROM EMPLOYEES;
    What I want to do:
    CREATE VIEW "HR"."EMP_NAME" ("FIRST_NAME", "LAST_NAME")(prmEMP_ID)
    AS
    SELECT FIRST_NAME, LAST_NAME FROM EMPLOYEES WHERE EMPLOYEE_ID IN (:prmEMP_ID);

    Blais wrote:
    How can I pass a parameter [bind variable or substitution variable] to a view in Oracle?
    Some will tell me that this is not necessary, that I can only pass the parameter when I query the view, but I found some case where this cause performance issue. In long view where I use subquery factoring [WITH], it's necessary to pass the parameter many time through different subqueries and not only to the resulting view.Yes, there can be performance issues. Views are a form of dynamic SQL and it is hard to predict how they will perform later.
    You can't pass parameters to a view. They are not functions. The mechanism to put the values in is what you mentioned, passing the parameter when you query the view.
    In other database (SQL Server, Access), we can pass parameters through query. I can't find how to do that in Oracle. Can some one tell me what is the approach suggest by Oracle on that subject? This functionality is not supported.
    What I can do:
    CREATE VIEW "HR"."EMP_NAME" ("FIRST_NAME", "LAST_NAME")
    AS
    SELECT FIRST_NAME, LAST_NAME FROM EMPLOYEES;
    What I want to do:
    CREATE VIEW "HR"."EMP_NAME" ("FIRST_NAME", "LAST_NAME")(prmEMP_ID)
    AS
    SELECT FIRST_NAME, LAST_NAME FROM EMPLOYEES WHERE EMPLOYEE_ID IN (:prmEMP_ID);Include the bind value when you use the view in a SELECT. The value will be applied to the view at run-time, somthing like
    CREATE  VIEW "HR"."EMP_NAME_VW" ("FIRST_NAME", "LAST_NAME","EMPLOYEE_ID")(prmEMP_ID)
    AS  SELECT FIRST_NAME, LAST_NAME FROM EMPLOYEES;
    select *
      from emp_name_vw
      WHERE EMPLOYEE_ID IN (:prmEMP_ID);To use EMPLOYEE_ID I added it to your list of columns in the view so it can be referenced in the WHERE clause. If you don't want to see that value don't select it from the view.

  • I want to remove bind variables in my data like & and many

    I have a field that holds description of a code and this is having bind variables (special characters). I need to remove them and replace with no value.
    I was trying with following sql and the dialog box (Enter Substitution Variable)is opening when I tried to execute the sql.
    select regexp_replace('B VOC AC & HEATING (*[[:punct:]])', '') from dual;
    please provide me the SQL how to do this
    Thanks in advance

    Hi,
    It looks like your question is about Substitution Variables, that typically look like &start_date or &1.  Bind Variables are completely different.
    By default, SQL*Plus, and some other front ends, expect that & will be followed by a substitution variable name.  If you're not using substitution variables, and you want to treat & as a normal character, then use Pablolee's suggestion.  SET DEFINE OFF will make SQL*Plus treat & as a normal character until you end the SQL*Plus session, or you explicitly cancel it by saying SET DEFINE ON.
    By the way, did you mean to call REGEXP_REPLACE with 2 arguments, like you posted
    select regexp_replace('B VOC AC & HEATING (*[[:punct:]])', '') from dual;
    or with 3 arguments, something like this
    select  regexp_replace ( 'B VOC AC & HEATING'
                           , '(*[[:punct:]])'    -- Round parentheses, '(' and ')', are not doing anything in this case
                           , ''                  -- NULL might be clearer
    from    dual;
    ?  Also, '*' in a regular expression p
    attern, means "the last item can occur 0 or more times".  In your code, there isn't any "last item" before the '*',  What are you trying to do?  Post some sample data (CREATE TABLE and INSERT statements) for a few different sample cases, and the results you want from that sample data.
    See the forum FAQ: https://forums.oracle.com/message/9362002

  • Bind Variable error in script

    Following piece of code when removed my procedure executes without any error. But when included it shows error.
    Bind Variable "mi" is NOT DECLARED.
    I am not getting what is the problem with the code.
    i am using oracle 11g.
    --increment day
    v_hour_counter:=v_hour_counter+1;
    if v_hour_counter>=24 then
    v_hour_counter:=0;
    v_calCurrentDate:=null;
    select to_char(to_date(v_calDate,'dd/mm/rrrr hh24:mi:ss')+1,'dd/mm/rrrr hh24:mi:ss')
    into v_calCurrentDate
    from dual;
    select to_date(v_calDate,'dd/mm/rrrr hh24:mi:ss')+1
    into v_calDate
    from dual;
    end if;
    --end increment day
    --increment hours
    select to_char(to_date(v_calCurrentDate,'dd/mm/yyyy hh24:mi:ss')+1/24,'dd/mm/yyyy hh24:mi:ss')
    into v_calCurrentDate
    from dual;
    --end increment hours
    DBMS_OUTPUT.PUT_LINE('*v_equipment_id* :' || v_equipment_id);
    DBMS_OUTPUT.PUT_LINE('*date* :' || v_cerresult);
    DBMS_OUTPUT.PUT_LINE('*v_cerresult* :' || v_cerresult);
    --DBMS_OUTPUT.PUT_LINE(':' || v_calCurrentDate);
    INSERT INTO T_CALCULATED_CER ( EQUIPMENT_NO,
    CER_FOR_DATE,
    BOILER_CALCULATED_CER,
    CREATED_BY,
    CREATED_DATE,
    UPDATED_DATE )
    VALUES ( v_equipment_id,
    to_date(v_calCurrentDate,'dd/mm/yyyy hh24:mi:ss'),
    v_cerresult,
    (select USF_GET_CONFIG('SYS_USER','CH') from dual),
    sysdate,
    sysdate);
    Need help..
    regards,
    Amit

    >
    to_date(v_calCurrentDate,'dd/mm/yyyy hh24:mi:ss'),
    >
    The ':mi' above is being interpreted as a bind variable in sql*plus.
    Use SET DEF OFF to stop that.
    See the SQL*Plus User's Guide
    http://docs.oracle.com/cd/B28359_01/server.111/b31189/ch12040.htm
    >
    SET DEF[INE] {& | c | ON | OFF}
    Sets the character used to prefix substitution variables to c.
    ON or OFF controls whether SQL*Plus will scan commands for substitution variables and replace them with their values. ON changes the value of c back to the default '&', not the most recently used character. The setting of DEFINE to OFF overrides the setting of the SCAN variable.
    See SET SCAN ON(obsolete) for more information on the SCAN variable.

  • How to pass a list as bind variable?

    How can I pass a list as bind variable in Oracle?
    The following query work well in SQL Developer if I set ":prmRegionID=2".
    SELECT COUNTRY_ID,
    COUNTRY_NAME
    FROM HR.COUNTRIES
    WHERE REGION_ID IN (:prmRegionID);
    The problem is that I can't find how to set ":prmRegionID=2,3".
    I know that I can replace ":prmRegionID" by a substitution variable "&prmRegionID". The above query work well with"&prmRegionID=2" and with "&prmRegionID=2,3".
    But with this solution, I lost all advantage of using binds variables (hard parse vs soft parse, SQL injection possibility, etc.).
    Can some one tell me what is the approach suggest by Oracle on that subject? My developer have work a long time too find how but didn't found any answer yet.
    Thank you in advance,
    MB

    Blais wrote:
    The problem is that I can't find how to set ":prmRegionID=2,3".Wrong problem. Setting the string bind variable to that means creating a single string that contains the text "+2,3+". THE STRING DOES NOT CONTAIN TWO VALUES.
    So the actual problem is that you are using the WRONG data type - you want a data type that can have more than a single string (or numeric) value. Which means that using the string (varchar2) data type is the wrong type - as this only contains a single value.
    You need to understand the problem first. If you do not understand the problem, you will not realise or understand the solution too.
    What do you want to compare? What does the IN clause do? It deals with, and compares with, a set of values. So it needs a set data type for the bind variable. A set data type enables you to assign multiple values to the bind variable. And use this bind variable for set operations and comparisons in SQL.
    Simple example:
    SQL> --// create a set data type
    SQL> create or replace type TStringSet is table of varchar2(4000);
      2  /
    Type created.
    SQL>
    SQL>
    SQL> var c refcursor
    SQL>
    SQL> --// use set as bind variable
    SQL> declare
      2          names   TStringSet;
      3  begin
      4          --// assign values to set
      5          names := new TStringSet('BLAKE','SCOTT','SMITH','KING');
      6 
      7          --// use set as a bind variable for creating ref cursor
      8          open :c for
      9                  'select * from emp where ename in (select column_value from TABLE(:bindvar))'
    10          using names;
    11  end;
    12  /
    PL/SQL procedure successfully completed.
    SQL> print c
         EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
          7698 BLAKE      MANAGER         7839 1981/05/01 00:00:00       2850                    30
          7788 SCOTT      ANALYST         7566 1987/04/19 00:00:00       3000                    20
          7369 SMITH      CLERK           7902 1980/12/17 00:00:00        800                    20
          7839 KING       PRESIDENT            1981/11/17 00:00:00       5000                    10
    SQL>
    SQL> --// alternative set comparison
    SQL> declare
      2          names   TStringSet;
      3  begin
      4          --// assign values to set
      5          names := new TStringSet('BLAKE','SCOTT','SMITH','KING');
      6 
      7          --// use set as a bind variable for creating ref cursor
      8          open :c for
      9                  'select * from emp where TStringSet(ename) submultiset of (:bindvar)'
    10          using names;
    11  end;
    12  /
    PL/SQL procedure successfully completed.
    SQL> print c
         EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
          7369 SMITH      CLERK           7902 1980/12/17 00:00:00        800                    20
          7698 BLAKE      MANAGER         7839 1981/05/01 00:00:00       2850                    30
          7788 SCOTT      ANALYST         7566 1987/04/19 00:00:00       3000                    20
          7839 KING       PRESIDENT            1981/11/17 00:00:00       5000                    10
    SQL>

  • EA3/EA2/EA1 - Bind Variables in PL/SQL

    EA1 seems to have taken a backward step when it comes to supporting bind variables in PL/SQL.
    Back in 1.1.3, according to the bugs fixed list, we apparently fixed bug 5884935 (BINDS IN A PL/SQL STATEMENT HAS "NOT ALL VARIABLES BOUND" ERROR), although this was only ever when running as scripts (as per Bind variables in PLSQL bug not fixed?
    Now according to the 1.2 documentation, bind variables are not supported in the script runner (section 1.7.2) and the SQL*Plus variable command is not supported (section 1.7.1). However, I can run the following code "successfully" (no errors reported but the substitution text entered does not appear in the dbms_output):
    variable bind_text varchar2(30);
    declare
    l_text varchar2(30);
    begin
    :bind_text := '&sub_text';
    dbms_output.put_line('Bind text: "' || :bind_text || '"');
    end;
    Now in EA1, running this as a script results in "ORA-01006: bind variable does not exist"
    Running the variable statement results in "ORA-00900: Invalid SQL Statement" and running the PL/SQL results in "ORA-1008: not all variables bound".
    Can someone from the SQL Developer team please comment on the intended support for bind variables in PL/SQL?
    Thanks,
    theFurryOne

    I know that the variable command isn't supported (as I said above), but that was also the case in 1.2, where it did actually sort of work.
    I am not talking about local PL/SQL variables declared within the PL/SQL - I am trying to get user entered values into the PL/SQL in the same way as prompting for bind variable values in SQL.
    So using SQL Developer bind variables inside PL/SQL is my end goal - preferably when running anonymous PL/SQL blocks as statements in the worksheet.
    However, as there have been "fixed" bugs to enable bind variables in PL/SQL, which require the use of SQL Plus commands that are not supported in SQL Developer (ie variable), I am trying to work out what the development team think the intended support for bind variables in PL/SQL is. Then I will know if what I want needs to be reported as a bug or logged as an enhancement request.
    theFurryOne

  • How to make a bind variable out of a comparison like statement

    I have a statement similar to the following -
    select x from atable where acolumn like '1%';
    How do I turn that into a variable in an anonymous block like -
    declare
    l_var varchar2(1) := '1';
    begin
    select x from atable where acolumn like 'l_var%'
    end;
    I need to prevent the database from using a literal in the plan so I need to convert like '%1' into a variable.
    Any suggestions?

    Not quite sure what you mean by 'binding' or 'substitution'.
    If you mean bind variables, the yes oracle does automatically use bind variables:
    SQL> CREATE TABLE atable
      2  (
      3          x VARCHAR2(10)
      4  )
      5  /
    Table created.
    SQL>
    SQL> INSERT INTO atable VALUES ('1234');
    1 row created.
    SQL> COMMIT;
    Commit complete.
    SQL>
    SQL> set serveroutput on size unlimited
    SQL>
    SQL> declare
      2    l_var atable.x%TYPE := '1';
      3    l_str atable.x%TYPE;
      4  begin
      5    select x
      6      into l_str
      7      from atable
      8     where x like l_var || '%';
      9
    10    dbms_output.put_line ('l_str = "' || l_str || '"');
    11  end;
    12  /
    l_str = "1234"
    PL/SQL procedure successfully completed.
    SQL>
    SQL> SELECT SQL_TEXT FROM v$sql WHERE sql_text LIKE 'SELECT %ATABLE%' AND sql_text NOT LIKE '%V$SQL%';
    SQL_TEXT
    SELECT X FROM ATABLE WHERE X LIKE :B1 || '%'
    SQL>Where that is the sql statement that the sql engine actually ran on behalf of the pl/sql routine.
    GP>

  • How to declare a bind variable with 'date' data type in command prompt?

    how to declare a bind variable with 'date' data type in command prompt?
    sql>variable q date;
    when i execute it show list of datatypes

    Hi,
    As Lokanath said, there are no DATE bind variables.
    You can use a VARCHAR2 bind variable, and convert it to a DATE in your SQL statment.
    If you're using SQL*Plus, consider a substitution variable. It won't be as efficient as a bind variable, but it will be as convenient.
    For example:
    DEFINE  first_entrry_date = "DATE '2010-06-20''
    SELECT   ...
    WHERE   entry_date >= &first_entry_date
    {code}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Slow Query over Database Link with Bind Variable

    I have a query over a DB link, with all tables on the remote database.
    If I use a bind variable (from Toad), the query takes 4 minutes. If I replace the bind variable with a constant or substitution variable, it takes 1 second.
    The query runs fine when run directly on the remote database using bind variable.
    9.2.0.7

    Look up "Bind variable peeking"
    What's happened is you have an execution plan that differs from the one with the constant. Why? My bet is that Oracle "peeked" at the bind variable to help it decide which execution plan to build. It then cached it. It probably cached an execution with an index when it should be doing a full table scan or a hash join instead of a nested loop. It's hard to say specifically what it is.
    Try this, flush your shared pool and rerun the query with the bind and let us know if it takes 1 second or 4 minutes. If it takes 1 second, then that was probably it.
    Read part 2 of Tom Kyte's blog post on what it is and it's behavior.
    http://tkyte.blogspot.com/2007/09/sqltracetrue-part-two.html

  • Declaring bind variables using decimals

    I'm on Oracle 11.2
    In SQL Developer, I'm having hard time executing a SQL with a bind variable. Below is the test table.
    create table TEST1 (TYP varchar2(3), NUM number(30,18)); 
    insert into TEST1 values ('TTT', 45.15168794137111); 
    commit; 
    Then I execute the below query and it returns no results. Why?
    VARIABLE P1 number; 
    EXEC :P1 := 45.15168794137111; 
    select * from TEST1 where NUM = :P1; 
    The above works in SQL Plus.

    That replaces the SQL before it executes it. It is just like using literals. I wanted to use bind variables for performance testing purposes.
    See the sql developer documentation:
    http://docs.oracle.com/cd/E10405_01/doc/appdev.120/e10406.pdf
    Run Script executes all statements in the Enter SQL Statement box using the Script
    Runner. The SQL statements can include substitution variables (but not bind
    variables) of type VARCHAR2 (although in most cases, VARCHAR2 is
    automatically converted internally to NUMBER if necessary); a pop-up box is
    displayed for entering substitution variable values.
    Notice the 'but not bind variables'

  • Report Performance with Bind Variable

    Getting some very odd behaviour with a report in APEX v 3.2.1.00.10
    I have a complex query that takes 5 seconds to return via TOAD, but takes from 5 to 10 minutes in an APEX report.
    I've narrowed it down to one particular bind. If I hard code the date in it returns in 6 seconds, but if I let the date be passed in from a parameter it takes 5+ minutes again.
    Relevant part of the query (an inline view) is:
    ,(select rglr_lect lect
    ,sum(tpm) mtr_tpm
    ,sum(enrols) mtr_enrols
    from ops_dash_meetings_report
    where meet_ev_date between to_date(:P35_END_DATE,'DD/MM/YYYY') - 363 and to_date(:P35_END_DATE,'DD/MM/YYYY')
    group by rglr_lect) RPV
    I've tried replacing the "to_date(:P35_END_DATE,'DD/MM/YYYY') - 363" with another item which is populated with the date required (and verified by checking session state). If I replace the :P35_END_DATE with an actual date the performance is fine again.
    The weird thing is that a trace file shows me exactly the same Explain Plan as the TOAD Explain where it runs in 5 seconds.
    Another odd thing is that another page in my application has the same inline view and doesn't hit the performance problem.
    The trace file did show some control characters (circumflex M) after each line of this report's query where these weren't anywhere else on the trace queries. I wondered if there was some sort of corruption in the source?
    No problems due to pagination as the result set is only 31 records and all being displayed.
    Really stumped here. Any advice or pointers would be most welcome.
    Jon.

    Don't worry about the Time column, the cost and cardinality are more important to see whther the CBO is making different decisions for whatever reason.
    Remember that the explain plan shows the expected execution plan and a trace shows the actual execution plan. So what you want to do is compare the query with bind variables from an APEX page trace to a trace from TOAD (or sqlplus or whatever). You can do this outside APEX like this...
    ALTER SESSION SET EVENTS '10046 trace name context forever, level 1';Enter and run your SQL statement...;
    ALTER SESSION SET sql_trace=FALSE;This will create a a trace file in the directory returned by...
    SELECT value FROM v$parameter WHERE name = 'user_dump_dest' Which you can use tkprof to format.
    I am assuming that your not going over DB links or anything else slightly unusual?
    Cheers
    Ben

  • How to Dene a Data Link Between Queries: Bind Variables

    This is an interesting topic and I cannot get it to work using Bind Variables.
    I have 2 queries: Q1 and Q2. Q2 needs c_id, account_code and account_type from Q1.
    Whe I run the data template below, I get only the data for Q1.
    Now people may argue that there is no data in Q2 for the relevant clause. So if I even remove the where clause in Q2 I still get no joy i.e Data appears for Q1 but not for Q2
    <dataTemplate name="FLCMR519_DATA_SET" description="Termination Quote Report">
         <parameters>
              <parameter name="cid" dataType="number" defaultValue="1"/>
              <parameter name="p_cln_id" dataType="number" defaultValue="62412"/>
         </parameters>
         <dataQuery>
              <sqlStatement name="Q1">
                   <![CDATA[SELECT qm.qmd_id,
    qm.contract_period,
    qm.quo_quo_id||'/'||qm.quote_no||'/'||qm.revision_no reference_no,
    qm.contract_distance,
    qm.mdl_mdl_id,
    q.qpr_qpr_id,
    q.quo_id,
    q.drv_drv_id,
    qm.revision_user username,
    pb.first_name||' '||pb.last_name op_name,
    pb.telephone_no,
    pb.facsimile_no,
    pb.email,
    q.c_id c_id,
    q.account_type account_type,
    q.account_code account_code,
    m.model_desc,
    ph.payment_description payment_head_desc,
    cl.fms_fms_id,
    cl.start_date,
    cl.end_date,
    cl.actual_end_date,
    cl.con_con_id,
    cl.cln_id,
    cl.term_qmd_id term_qmd_id,
    qm2.contract_period term_period,
    qm2.contract_distance term_distance
    FROM quotations q,
               quotation_models qm,
               contract_lines cl,
               personnel_base pb,
               models m,
               model_types mt,
               payment_headers ph,
               quotation_models qm2
    WHERE q.quo_id = qm.quo_quo_id
           AND cl.cln_id = :p_cln_id
           AND qm.qmd_id = cl.qmd_qmd_id
           AND qm2.revision_user = pb.employee_no (+)
           AND qm.mdl_mdl_id = m.mdl_id
           AND m.mtp_mtp_id = mt.mtp_id
           AND qm.payment_id = ph.payment_header_id
           AND qm2.qmd_id (+) = cl.term_qmd_id
    ]]>
              </sqlStatement>
              <sqlStatement name="Q2">
                   <![CDATA[SELECT ea.c_id,                  ea.account_type,ea.account_code,ea.account_name
    FROM external_accounts ea
                 WHERE ea.c_id = :c_id
                   AND ea.account_type = :account_type
                   AND ea.account_code = :account_code
    ]]>
              </sqlStatement>
         </dataQuery>
    </dataTemplate>

    Defining dataStructure section is mandatory for multiple queries.

  • Can I use bind variable instaed of writing static COLUMN Name

    Hi , I am having a table containing id and column names, the data is stored against that id in other tables. Now I wish to update data into another table so that it goes into apppropriate column without using decode function.
    I am trying to do this:
    EXECUTE IMMEDIATE 'update TEST set :1 = :2
    where PROJECT_ID= :3 and UNIQUE_ID= :4' using P_DEST_COLUMN, P_TEXT_VALUE, P_PROJ_ID, P_TASK_UID;
    the values P_DEST_COLUMN, P_TEXT_VALUE, P_PROJ_ID, P_TASK_UID are populated using a cursor in PL/SQl
    Is this statement valid? If not can you tell me how to do it as I am getting some error I am unable to comprehend.
    thanks
    Rishabh

    Column names cannot be substituted at run-time as bind variables. If you need to specify the column name at run-time, you'd need to construct a new string and execute that string dynamically, i.e.
    EXECUTE IMMEDIATE 'UPDATE test SET ' || p_dest_column || ' = :1 ' || ...From a data model standpoint, storing column names as data elements in another table is generally a rather poor idea. It's likely to make ad-hoc reporting nearly impossible and to cause a lot more parsing than would otherwise be required.
    Justin

  • Dynamic sql and bind variables

    Hi,
    I have a stored procedure which filters a table on 5 five columns. The filters come from the input parameters,
    and these 5 parameters can come in any combination, I mean some of them may be null and some of them may not be null.
    So I constructed the where filter of the query with IF blocks like the following:
    dynamic_query := 'select * from TESTTABLE where 1= 1';
    IF (P1 is not null) THEN
    dynamic_query := dynamic_query || ' AND column1 = :1';
    END IF;
    IF (P2 is not null) THEN
    dynamic_query := dynamic_query || ' AND column2 = :2';
    END IF;
    IF (P3 is not null) THEN
    dynamic_query := dynamic_query || ' AND column3 = :3';
    END IF;
    IF (P4 is not null) THEN
    dynamic_query := dynamic_query || ' AND column4 = :4';
    END IF;
    IF (P5 is not null) THEN
    dynamic_query := dynamic_query || ' AND column5 = :5';
    END IF;
    OPEN CUR_OUT FOR dynamic_query USING P1, P2, P3, P4, P5;
    The problem is how can I construct the USING and bind parameters, I cannot use "USING P1, P2, P3, P4, P5" because some of bind variables
    may not be in dynamic query if the input parameters are null. Is there a way to overcome this problem without writing all the 2 ^ 5 combinations?
    Any help is greatly appreciated.

    here it is in the Tomer Cohen way:
    IF (P1 is not null) THEN
    dynamic_query := dynamic_query || ' AND column1 = :1';
    ELSE
    dynamic_query := dynamic_query || ' AND  :1 IS NULL';
    END IF;
    IF (P2 is not null) THEN
    dynamic_query := dynamic_query || ' AND column2 = :2';
    ELSE
    dynamic_query := dynamic_query || ' AND  :2 IS NULL';
    END IF;
    IF (P3 is not null) THEN
    dynamic_query := dynamic_query || ' AND column3 = :3';
    ELSE
    dynamic_query := dynamic_query || ' AND  :3 IS NULL';
    END IF;
    IF (P4 is not null) THEN
    dynamic_query := dynamic_query || ' AND column4 = :4';
    ELSE
    dynamic_query := dynamic_query || ' AND  :4 IS NULL';
    END IF;
    IF (P5 is not null) THEN
    dynamic_query := dynamic_query || ' AND column5 = :5';
    ELSE
    dynamic_query := dynamic_query || ' AND -1 = :5';
    END IF;
    OPEN CUR_OUT FOR dynamic_query USING P1, P2, P3, P4, P5;Amiel Davis

Maybe you are looking for

  • Console keeps opening

    I have a Macbook Air with Mavericks. When I startup from shutdown or sleep mode, the Console application opens up. Is there a way for this not to occur?

  • Partitioning new disk in AIF: cfdisk and fdisk disagree?

    I am trying to install Arch for the first time and I am trying to do it on a new machine. I used the cfdisk programme to partition my disk. I made sure that no partition had an asterisk so they would all be aligned. However, fdisk -l now tells a diff

  • Adding text to a target box??!!

    Hi there, Ive made a trigger and target so when i roll over an image the target box fades in with a light opacity fill over the image which gives it a nice effect. Now I want to add text on that target box so when the fill colour fades in some full o

  • Adobe Muse 1.0 Shutdown Bug!

    On Export to HTML,  this error comes up repeatedly and closes Muse abruptly! I can't work now. Got a deadline for tomorrow.

  • Create Container in Designer 6i

    Hi, I had a problem when try to create container in designer 6i, can anybody tell me what is the correct way to create the container? Everytime i try, after create new container, change the name and when i try to press OK button, nothing happen. The