Using package constants in package SQL - acts as bind variable or literal?

I'm looking for confirmation on the performance impact of using package constants in package SQL.
Let's say I have a number of queries in package code that refer to various literals that are prone to typos e.g. "CANCELLED" instead of "CANCELED". To reduce the chances of this happening, I have an APP_GLOBALS package where I declare constants for each literal:
C_CANCELED CONSTANT VARCHAR2(12) := 'CANCELED';And in queries that refer to literal 'CANCELED' I use APP_GLOBALS.C_CANCELED instead. This way the typo is caught during compilation. For example:
BEGIN
--Do something with all 'Canceled' orders
  FOR r IN (SELECT order_id
              FROM orders
             WHERE status = APP_GLOBALS.C_CANCELED)
  LOOP
  END LOOP;
END;Assume that:
- the STATUS column is indexed
- the possible values are PENDING, APPROVED, CANCELED
- a small percentage of orders are CANCELED
From the optimizer's perspective is the query equivalent to
SELECT order_id
  FROM orders
WHERE status = :varor
SELECT order_id
  FROM orders
WHERE status = 'CANCELED'?
According to what I see in v$sqltext_with_newlines, it's the first one. Can anyone suggest an alternative way of replacing literals in package SQL to prevent typos? Worst case, I suppose I can start with constants so that it compiles successfully then do a global replace of the constants with the literals.

Can anyone suggest an alternative way of replacing literals in package SQL to prevent typos?I cannot think of any. But, here is the thing. If the typos are there, then, it technically is a bug even though both the codes would compile. The bug will be hunted down when the program doesn't work as intended. Wouldn't most typos be caught in unit testing of the code?
Also, if you replace a string literal with a variable, then, maybe (just maybe, depending on your version of the dbms), it may end up picking a different execution plan. That might be an unintended consequence.

Similar Messages

  • Accessing package CONSTANT in a SQL query

    Hi,
    Can anybody explain why I cannot access the package constant in a SQL but can use it in dbms_output.put_line:
    SQL> create package scott.xx_test_const_pkg
    2 as
    3 a constant varchar2(1) :='A';
    4 end;
    5 /
    Package created.
    SQL> begin
    2 dbms_output.put_line( scott.xx_test_const_pkg.a);
    3 end;
    4 /
    A <------------------THIS WORKS
    PL/SQL procedure successfully completed.
    SQL> select * from scott.emp where ename=scott.xx_test_const_pkg.a;
    select * from scott.emp where ename=scott.xx_test_const_pkg.a <------------------THIS DOES NOT WORK
    ERROR at line 1:
    ORA-06553: PLS-221: 'A' is not a procedure or is undefined
    Thanks

    You can't refer to a pl/sql package constant in a sql statement.
    Create a function that returns the constant value and then refer to the function in a sql statement.

  • SQL query with Bind variable with slower execution plan

    I have a 'normal' sql select-insert statement (not using bind variable) and it yields the following execution plan:-
    Execution Plan
    0 INSERT STATEMENT Optimizer=CHOOSE (Cost=7 Card=1 Bytes=148)
    1 0 HASH JOIN (Cost=7 Card=1 Bytes=148)
    2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TABLEA' (Cost=4 Card=1 Bytes=100)
    3 2 INDEX (RANGE SCAN) OF 'TABLEA_IDX_2' (NON-UNIQUE) (Cost=3 Card=1)
    4 1 INDEX (FAST FULL SCAN) OF 'TABLEB_IDX_003' (NON-UNIQUE)
    (Cost=2 Card=135 Bytes=6480)
    Statistics
    0 recursive calls
    18 db block gets
    15558 consistent gets
    47 physical reads
    9896 redo size
    423 bytes sent via SQL*Net to client
    1095 bytes received via SQL*Net from client
    3 SQL*Net roundtrips to/from client
    1 sorts (memory)
    0 sorts (disk)
    55 rows processed
    I have the same query but instead running using bind variable (I test it with both oracle form and SQL*plus), it takes considerably longer with a different execution plan:-
    Execution Plan
    0 INSERT STATEMENT Optimizer=CHOOSE (Cost=407 Card=1 Bytes=148)
    1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TABLEA' (Cost=3 Card=1 Bytes=100)
    2 1 NESTED LOOPS (Cost=407 Card=1 Bytes=148)
    3 2 INDEX (FAST FULL SCAN) OF TABLEB_IDX_003' (NON-UNIQUE) (Cost=2 Card=135 Bytes=6480)
    4 2 INDEX (RANGE SCAN) OF 'TABLEA_IDX_2' (NON-UNIQUE) (Cost=2 Card=1)
    Statistics
    0 recursive calls
    12 db block gets
    3003199 consistent gets
    54 physical reads
    9448 redo size
    423 bytes sent via SQL*Net to client
    1258 bytes received via SQL*Net from client
    3 SQL*Net roundtrips to/from client
    1 sorts (memory)
    0 sorts (disk)
    55 rows processed
    TABLEA has around 3million record while TABLEB has 300 records. Is there anyway I can improve the speed of the sql query with bind variable? I have DBA Access to the database
    Regards
    Ivan

    Many thanks for your reply.
    I have run the statistic already for the both tableA and tableB as well all the indexes associated with both table (using dbms_stats, I am on 9i db ) but not the indexed columns.
    for table I use:-
    begin
    dbms_stats.gather_table_stats(ownname=> 'IVAN', tabname=> 'TABLEA', partname=> NULL);
    end;
    for index I use:-
    begin
    dbms_stats.gather_index_stats(ownname=> 'IVAN', indname=> 'TABLEB_IDX_003', partname=> NULL);
    end;
    Is it possible to show me a sample of how to collect statisc for INDEX columns stats?
    regards
    Ivan

  • ADF jdev10: SQL TRUNC with bind variable in sql statement in VO

    Hi,
    In VO in where clause:
    TRUNC(ServiceRequest.REQUEST_DATE) > :MyDate works fine!
    But TRUNC(ServiceRequest.REQUEST_DATE) > TRUNC(:MyDate) doesn't work!
    "SQL Query Error Message: ORA-00932: inconsistient datatypes: expected DATE got NUMBER"
    How to use TRUNC function for a bind variable?

    Basementjack,
    Any of these solutions that you are doing have possible performance implications in the database side, as you are applying a function to a database column; this is generally going to preclude the use of an index.
    Assuming that you are trying to find service requests that were before the date that is being passed in in the bind variable, and assuming that both the bind variable and service request date can have time components, you could try:
    ServiceRequest.REQUEST_DATE <= TO_DATE(trunc(:MyDate) - 1/86400)Does this do what you want?
    John

  • How to use SYSDATE as a default value of a bind variable in a query report?

    Hi,
    I want to use SYSDATE as default value for a bind variable in Query based report.
    I don't see any way to do it, someone helps?
    Thanks a lot.
    Paulo.

    You can aslo use #sysdate directly.
    Hi,
    The way I'm doing in my report is, I have a database function (f_ret_sysdate) with the following code
    create function f_ret_sysdate return varchar2
    begin
    return to_char(sysdate,'mm/dd/yyyy');
    end;
    Now, in the 'Customization Form Display Options' section of the report I'm calling this function as #f_ret_sysdate in the default value field of corresponding bind variable to display SYSDATE with the format.
    Hope this helps!...
    -Krishnamurthy

  • How to run a sql statement with bind variable in a test environment

    Hello,
    I have a sql statement in prod that I like to run in test. I got the sql statement from statspack, but the statement has bind variables. How do I get this statement to run in test? Thank you.

    Hi,
    If you have the SQL statement and all the referenced objects are available in your test env then what is the problem to run it?
    If I am not wront to get your reqmnt...
    i.e
    SQL> select * from emp
    where emp_no = &empno
    and dept_code = &deptcode;
    Thanks

  • Package constants in DBMS_CRYPTO

    Anyone any idea why I can't reference the constants in the DBMS_CRYPTO package.
    I've looked in the package spec and they are there, and if I use the actual value then that works fine, but I can't reference it by name for some reason.
    SQL> create view vw_tab1 as select myid, dbms_crypto.hash(myclob, DBMS_CRYPTO.HASH_SH1) as myclob from mytab1;
    create view vw_tab1 as select myid, dbms_crypto.hash(myclob, DBMS_CRYPTO.HASH_SH1) as myclob from mytab1
    ERROR at line 1:
    ORA-06553: PLS-221: 'HASH_SH1' is not a procedure or is undefined
    SQL> create view vw_tab1 as select myid, dbms_crypto.hash(myclob, 3) as myclob from mytab1;
    View created.
    SQL>

    Hello
    It's not just dbms_crypto, it's package constants in general:
    SQL> create or replace package pkg_test
      2  as
      3  pc_test_const constant number:=1;
      4  end;
      5  /
    Package created.
    SQL> select pkg_test.pc_test_const from dual;
    select pkg_test.pc_test_const from dual
    ERROR at line 1:
    ORA-06553: PLS-221: 'PC_TEST_CONST' is not a procedure or is undefined
    SQL> select to_char(pkg_test.pc_test_const) from dual;
    select to_char(pkg_test.pc_test_const) from dual
    ERROR at line 1:
    ORA-06553: PLS-221: 'PC_TEST_CONST' is not a procedure or is undefinedI had a look in the docs to try to find the reason but I couldn't.
    HTH
    David

  • How to find out if a SQL is using a bind variable or not?

    In order to make a SQL use consistent execution plan, I want to create a profile for a SQL. But I need to know if a SQL is using bind variable or not to create a profile for all the same SQLs except the literal value. How can I do that?
    Thanks in advance

    You can tell if an SQL statement uses a bind variable by looking at the SQL statement.
    If you look in the program that submits the SQL statement you can see how it constructs, prepares, and executes the statement.
    If you are just looking at the SQL in the shared pool then depending on how the statement is written and the setting of database parameters like cursor sharing then it can be more difficult but if you see a constant (actual value) that is a constant. A bind variable would appear as a name in the where clause where that name does not exist any of the tables referenced in the query. Note it is technically possible to create pl/sql variables with the same name as columns in the query but that is poor coding and leads to issues.
    Note - To Oracle two versions of the otherwise same query where one has a constant and the other has a bind variable are not the same query and often produce different plans. This is a common error made by developers new to Oracle when using explain plan. To explain a query that uses bind variables place a ":" in front of the variable name in the SQL submitted to explain plan.
    HTH -- Mark D Powell --

  • Using bind variables (in & out) with dynamic sql

    I got a table that holds pl/sql code snippets to do validations on a set of data. what the code basically does is receiving a ID and returning a number of errors found.
    To execute the code I use dynamic sql with two bind variables.
    When the codes consists of a simpel query, it works like a charm, for example with this code:
    BEGIN
       SELECT COUNT (1)
       INTO :1
       FROM articles atl
       WHERE ATL.CSE_ID = :2 AND cgp_id IS NULL;
    END;however when I get to some more complex validations that need to do calculations or execute multiple queries, I'm running into trouble.
    I've boiled the problem down into this:
    DECLARE
       counter   NUMBER;
       my_id     NUMBER := 61;
    BEGIN
       EXECUTE IMMEDIATE ('
          declare
             some_var number;
          begin
          select 1 into some_var from dual
          where :2 = 61;
          :1 := :2;
          end;
          USING OUT counter, IN my_id;
       DBMS_OUTPUT.put_line (counter || '-' || my_id);
    END;this code doesn't really make any sense, but it's just to show you what the problem is. When I execute this code, I get the error
    ORA-6537 OUT bind variable bound to an IN position
    The error doesn't seem to make sense, :2 is the only IN bind variable, and it's only used in a where clause.
    As soon as I remove that where clause , the code will work again (giving me 61-61, in case you liked to know).
    Any idea whats going wrong? Am I just using the bind variables in a way you're not supposed to use them?
    I'm using Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit

    Correction. With execute immediate binding is by position, but binds do not need to be repeated. So my statement above is incorrect..
    You need to bind it once only - but bind by position. And the bind must match how the bind variable is used.
    If the bind variable never assigns a value in the code, bind as IN.
    If the bind variable assigns a value in the code, bind as OUT.
    If the bind variable assigns a value and is used a variable in any other statement in the code, bind as IN OUT.
    E.g.
    SQL> create or replace procedure FooProc is
      2          cnt     number;
      3          id      number := 61;
      4  begin
      5          execute immediate
      6  'declare
      7          n       number;
      8  begin
      9          select
    10                  1 into n
    11          from dual
    12          where :var1 = 61;       --// var1 is used as IN
    13 
    14          :var2 := n * :var1;     --// var2 is used as OUT and var1 as IN
    15          :var2 := -1 * :var2;    --// var2 is used as OUT and IN
    16  end;
    17  '
    18          using
    19                  in out id, in out cnt;  --// must reflect usage above
    20 
    21          DBMS_OUTPUT.put_line ( 'cnt='||cnt || ' id=' || id);
    22  end;
    23  /
    Procedure created.
    SQL>
    SQL> exec FooProc
    cnt=-61 id=61
    PL/SQL procedure successfully completed.
    SQL>

  • Using bind variables in Oracle SQL developer

    Hi all,
    i am using Oracle SQL developer. i want to use the bind variable in my sql.
    variable myid number :=1;
    select * from mds_3618_request where id = :myid;
    but i am getting the below error.
    Error starting at line 2 in command:
    select * from mds_3618_request where id = :myid
    Error report:
    SQL Error: Missing IN or OUT parameter at index:: 1
    Does Oracle SQL developer support bind variables in the SQL statements?
    thanks in Advance
    Vali Shaik

    You are probable going to get a quicker answer on this forum : SQL Developer
    -- Andy

  • Correct Way to use Bind variables when using an MS SQL server backend

    Hey,
    I'm having some trouble figuring out how to use bind variables in a view when using an MS SQL server backend. For some reason when I'm using an ApplicationModule that has a MS SQL Server JDBC library loaded and I attempt to click OK when editing the following query:
    SELECT kit_status, component_id
    FROM numbered_inv
    WHERE trialname = :1
    I get an error stating that "SQL Query Error Message Incorrect Syntax near ':'". Is JDeveloper compatible with SQL server for bind variables because this query runs just fine if I replace the :1 with a say "Testing testing".
    Thanks in advance
    Edited by: NullCheck on Dec 15, 2010 2:06 PM

    Gotcha. I had tried %1% %0% ?0 and ?1 and various other permutations none of which worked. Got it working by setting the query to:
    SELECT kit_status, component_id
    FROM numbered_inv
    WHERE trialname = ?
    ORDER BY kit_status
    And then adding a bind variable with "Bind position" set to 0.
    Thanks again Shay!

  • Using Bind Variable in a SELECT

    Hi,
    I'm trying to build up my SQL query at run-time using bind variables and in the Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework 11g Release 1 (11.1.1) it says that 'After defining the bind variables, the next step is to reference them in the SQL statement. While SQL syntax allows bind variables to appear both in the SELECT list and in the WHERE clause, you'll typically use them in the latter context, as part of your WHERE clause.'.
    However, when I try to use the bind variables in my SELECT list because I've had to set a type for the variable to String the variable gets inserted with inverted commas either side e.g. SELECT 'Service' FROM TestTable. Is it possible to use bind variables to insert a value into my select list without these inverted commas around it?
    Thanks in advance,
    Tom

    OK, thanks for your response. Do you know of a way then where I can control my SELECT parameters programmatically? I'm currently trying to do it using the information in the chapter '35.9 Using Programmatic View Objects for Alternative Data Sources' from the Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework 11g Release 1 (11.1.1). I think I'm part way there, would this be the correct way of acheiving what I want?
    Cheers, Tom

  • ADF BC / Why bind variables are mandatory in the sql query

    I got this error during view object excecution in the component browser :
    (oracle.jbo.SQLStmtException) JBO-27122: Erreur SQL lors de la préparation d'une instruction. Instruction : SELECT * FROM (Select distinct(socialgroup.socialgroup_i) from socialgroup, socialgroupmember, lodgingallocation, lodge
    where socialgroup.socialgroup_i = socialgroupmember.socialgroup_i and socialgroupmember.t_socialgrouprole_i = t_rolegroup_ipar.fgetflextypologyclassitem_i(t_rolegroup_ipar.fisbeneficiary) and socialgroupmember.datefrom <= :DateTo and nvl(socialgroupmember.dateto, :DateFrom) >= :DateFrom and socialgroupmember.requester_i = lodgingallocation.requester_i and lodgingallocation.datefrom <= :DateTo and nvl(lodgingAllocation.DateTo, :DateFrom) >= :DateFrom and lodgingallocation.lodge_i = lodge.lodge_i) QRSLT ORDER BY "SOCIALGROUP_I"
    ----- LEVEL 1: DETAIL 0-----
    (java.sql.SQLException) Tentative de définition d'un nom de paramètre qui ne se trouve pas dans le SQL: T_SICategory_I
    The bind variables T_SICategory_I is not yet use in the sql query but will be used later so i defined it for the view object.
    Is it a reason that the run time check this ? It would be more convenient to set the bind variables early when defining the view object and add them later during the development iteration.

    Design-time defined named bind variables can be marked as required, or not.
    This is decided by the use in the where clause or in view criteria. In my case the bind variable was not used in where clause neither in view criteria and that causes the error.
    May be i would be nice to add a check box (a flag) that enable or disable the bind variables for this checking so we will be able to let it defined even we removed some part of the query corresponding to the corresponding restriction or we defined it earlier for a part of the query that is not yet defined.
    In my current case i fully defined the bind variables but would refine my query later ... in that cause i would have to remove this bind variable and loose all the definitions to run this view object.
    sorry for my english ...

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

  • Bind variables + SQL Developer

    Hi,
    I have a couple of very simple pl/sql scripts with bind variables (there are no cursors in the scripts) - when I execute these scripts in SQL Developer, it doesn't work as it should.
    It seems as if SQL developer doesn't register the bind variables - in one script, the first execution worked ok, but after that I need to comment the bind variable declarations, otherwise it does not work. In the other script, NULL value is assigned to the variable eventhough a number literal was assigned to the variable.
    When I execute the scripts in SQL*PLUS, they work just fine!
    Why is this? Is there something I need to know inorder to use bind variables in SQL Developer?
    Thanks!

    Once you use '&&', the only way to 'reset' the variables is by using UNDEFINE (just like SQL*Plus).
    ...Unless you run a second script from a second Tab within SQLDeveloper and the second script references the '&&' variables from the first. Then, you get prompted again. In this case, it doesn't seem to see the same '&&' variables that are set in the first script. The second tab seems to have it's own "state" -- something that doesn't happen in SQL*Plus because.......well, it doesn't have tabs.
    --s                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

Maybe you are looking for

  • Can I upgrade to the OS X Mavericks?

    I have recently purchased an early 2011 Macbook Pro 15"  It has 10.6.8 installed on it, can I safely upgrade to the OS X Mavericks?  Im a new Mac user, this is my first Mac. I purchased it online, refurbished, dont know if that matters or not.  But I

  • Can't copy or move iPhoto library because file is in use.

    I'm trying to copy my iPhoto library which is stored on an external drive, to my new Mac Mini. The external drive has been connected to my laptop, and the file has been my primary library for the laptop, which is a MacBook Pro running Mountain Lion,

  • Program to update BOM by CSAP_MAT_BOM_CREATE as error KEY_INCOMPLETE coming

    Hi to all, Can any one provide me sample program to update BOM via Function Module CSAP_MAT_BOM_CREATE. As i already have created the program , but run time error is coming KEY_INCOMPLETE for CSAP_MAT_BOM_CREATE. as i have already search the SDN , bu

  • "Adobe InDesign is shutting down. A serious error was detected. Please restart InDesign to recover w

    HELP! I am making a book in InDesign CS5. It contains 148 different ID documents. I'm ready to make my hi-res pdf to send to the print shop, however, each time I try to make it, I get the above error message. It appears to be exporting to pdf all the

  • Host command with 9i forms

    HI Gentlemen, I have a working forms application in 8i which I migrated to 9i. I have to export several tables by means of the exp utility. This will be called thru host('exp ...') in a WHEN-BUTTON-PRESSED trigger. Unfortunately, the command is skipp