Package body variable- is it always safe to use it?

In a package spec i have a function "function1" and in package body this functions does following:
1) it evaluate/calculate a variable/value "Flag1".
2) it calls 4 (package body) functions that needs to use value "Flag1".
I have forgotten how "package body variables" work. Is it safe to declare variable "Flag1" in a "package body" level? So that "function1" can initialize this variable and 4 functions can use this variable later too. Or it is not safe if i have lot of sessions in my database which may go into conflict with sharing this "flag1"? And i perhaps better send "flag1" as function parameter to all 4 functions?

Easy enough to test, but it depends on what you mean by the "next run".
In the same session:
SQL > CREATE PACKAGE p AS
  2     FUNCTION f1(p_v1 IN NUMBER) RETURN NUMBER;
  3  END;
  4  /
Package created.
SQL > CREATE PACKAGE BODY p AS
  2     g_var VARCHAR2(10);
  3
  4  FUNCTION f2(p_v2 IN VARCHAR2) RETURN NUMBER IS
  5  BEGIN
  6     DBMS_OUTPUT.Put_Line('Value of g_var in f2 is: '||g_var);
  7     RETURN 1;
  8  END;
  9
10  FUNCTION f1 (p_v1 IN NUMBER) RETURN NUMBER IS
11     l_res NUMBER;
12  BEGIN
13     DBMS_OUTPUT.Put_Line('Value of g_var at start f1 is: '||g_var);
14     SELECT dummy INTO g_var FROM dual;
15     l_res := f2(g_var);
16     g_var := 'A';
17     DBMS_OUTPUT.Put_Line('Value of g_var at end f1 is: '||g_var);
18     RETURN l_res;
19  END;
20  END;
21  /
Package body created.
SQL > var v number;
SQL > exec :v := p.f1(1);
Value of g_var at start f1 is:
Value of g_var in f2 is: X
Value of g_var at end f1 is: A
PL/SQL procedure successfully completed.
SQL > exec :v := p.f1(2);
Value of g_var at start f1 is: A
Value of g_var in f2 is: X
Value of g_var at end f1 is: A
PL/SQL procedure successfully completed.but after running it in one session, then doing the "next run" in a different session:
SQL > exec :v2 := p.f1(1);
Value of g_var at start f1 is:
Value of g_var in f2 is: X
Value of g_var at end f1 is: A
PL/SQL procedure successfully completed.John

Similar Messages

  • && Substitution Variable in Package Body using SQL Developer

    Hi Folks,
    I've moved over to working to in SQL Developer (its a very early version - 1.0.0) from a combination of SQL*Plus command line and a text editor. I'm trying to get this upgrgraded, but I think the question will be the same with a newer version anyway.
    I am creating a package, and in the package body I have some &&my_var substitutions that I was previoulsy prompted for when calling the .sql from the command line SQL*Plus. I need this as the variable needs to be different for the development and live environment.
    When working in SQL Developer, I can load the package body from Connection->Packages->My Package->My Package Body, and click the edit button to edit the code, however, when I click the Compile button in the top of the window my code error's because of the substituion variablle. An example is:
    CREATE OR REPLACE
    PACKAGE BODY MY_PACKAGE AS
    PROCEDURE MY_PROCEDURE
    BEGIN
    my_variable := &&my_function_from_live_or_dev_database
    END MY_PROCEDURE
    Can anyone tell me if there is a way of defining a compiler variable within the IDE widow while editing a package body stored in the database, without manually copying the code into the Worksheet and running it as a script?
    Thanks,
    AM

    953104 wrote:
    Thanks for the reply, the code was just quickly typed to show the sort of thing I am doing, it wasn't actual code form my project.
    I've come from a C background so what I would have done would be create a #define and changed to when on live or development - or passed the variable to the build environment from the IDE or makefiles and the change would have reflected through my whole project.
    What I want to be able to do is alter a definition of some sort that will reflect throughout my whole project, so I can change it in one location to minimize code changes before going live. I don't really want to be prompted at all. On one system it needs to be DEV_10 and on the other it needs to be LIVE_10.Is there a possibility to elimiante this difference at all?
    For example if DEV_10 is the oracle schemauser on the development database and LIVE_10 would be the one on the production system. THen you could just remove all references to the schema from your code.
    IF you are already connected to this schema, then you don't need to specify the schema name anymore.
    example
    instead of
    create or replace package dev_10.myPackage
    ...you can simply use
    create or replace package myPackage
    ...If needed you can alter the cuurently connected user just before you run the script.
    alter session set current_schema = LIVE10;
    create or replace package myPackage
    ...This would be a different working window in the developer (script worksheet, instead of direct pl/sql editor).
    Substitution variables are allowed there.

  • Bind variable issue in Package Body

    When I try to compile my package body, I get an error on the variables declared within the procedure. Bind variable not allowed. Any thoughts?

    Apparently the error was related to something else, and the message was mis-leading. When I re-structured the code for other reasons, the 'error' was no longer showing up. Sorry for the confusion.

  • Variable declaration in Package and package body

    Hi
    Kindly reply the difference in declaring a cursor inside a package vs package body
    eg:
    create or replace package shapak is
    cursor shacur is select * from sha;
    function shafun return number;
    end;
    i can declare the above cursor inside the package body withoout declaring in package specification. but what is the difference?
    reply appreciated
    thanks
    shajan

    In general..Items declared in the package spec are visible outside the package..so you can say public.where as items declared in the body are restricted to use within the package..such items are called private.

  • Sharing Package level variables in PL/SQL Libraries in Forms 6i and 10g

    We have a Forms 6i Application, where we share variables between Forms in the following way:
    In scheme A_PROMATA is a table called T_GLOBAL_VAR, where we define our variables as Columns of the table. That means there is no record in the table, just columns, that represent our “global” variables, we want to share between Forms.
    Then we have a PL/SQL Library called NAV, where we have only the Package Specifiation:
    PACKAGE NAV
    IS
    VAR A_PROMATA.T_GLOBAL_VAR%ROWTYPE;
    END;
    This works fine for years, but when we try to migrate to Forms 10g, this does not work anymore, because we always get the following error message:
    ORA-06508 PL/SQL: could not find program unit being called
    But when we create a Dummy-Package Body with a Dummy Procedure in the Package NAV in the library, it works again...
    Does anybody know the reason for this???
    Regards and Thanks.
    Udo
    p.s.:
    Database is 10g (10.1.0.4.0)
    Application Server is 10g (10.1.2.0.0) on Red Hat

    Have you generated (compiled) the runtime .plx from your PLL library using the 10g compiler? I use the command:
    f90genm LIBNAME un/pw@xyz Module_Type=LIBRARY Output_File=LIBNAME Strip_Source=YESI tried out your situation, creating a PLL library with ONLY a package spec, and only a table%Rowtype record within the spec. While I had problems getting the Forms 10 Builder to generate the PLL Library, I was able to create a test form that sets, and then displays the columns within the record within the package spec.
    I had problems generating the .plx from the .pll within the Forms Builder. It kept giving me errors:    FRM-91507: Internal Error: Unable to generate library.
    and
        PDE-CCR003 Library TMP3 is currently in use.The only way I could create the .plx was from a cmd.exe window, with the batch compiler command above.

  • 3.1EA2 bug still not fixed - Members of package body not listed in the tree

    Hi, I was working today with SQL Developer again and found that this bug is still not fixed even when it was reported more than 1 year ago!!!
    I did a quick search and found it here
    Package Body Tree not always showing
    The problem is when you expand the package specification or package body tree, not all members of the specification/body are listed. This is mostly observable in the package body, but it regards to the specification as well.
    Consider this case:
    CREATE TABLE EMP (
        ID               NUMBER(6,0) DEFAULT 0,
        NAME             VARCHAR2(20 BYTE) DEFAULT NULL,
        DEPT             VARCHAR2(20 BYTE) DEFAULT NULL,
        FUNCTION         VARCHAR2(20 BYTE),
        PROCEDURE        VARCHAR2(20 BYTE));
    CREATE TABLE LOOP (
      AREA    VARCHAR2(5),
      VALUE   VARCHAR2(2));
    CREATE OR REPLACE PACKAGE Test_Package1 AS
    gvc_const CONSTANT VARCHAR2(10) := 'xxx';
    PROCEDURE Test(p_RC OUT NUMBER,
                   p_ID IN NUMBER);
    END Test_Package1;
    CREATE OR REPLACE PACKAGE BODY Test_Package1 AS
    PROCEDURE Test(p_RC OUT NUMBER,
                   p_ID IN NUMBER)
    IS
    BEGIN
      --INSERT INTO EMP (ID, NAME, DEPT, PROCEDURE) VALUES (1, 'Tina', 'xxx', 'xxx');
      --INSERT INTO EMP (ID, NAME, DEPT, FUNCTION) VALUES (2, 'Jeff', 'xxx', 'xxx');
      --INSERT INTO LOOP(AREA, VALUE) VALUES('a','b');
      NULL;
    END;
    END Test_Package1;Compile the package specification and the body. Expand the spec + body in the tree. Uncomment any of the commented lines in the package body and compile the body again. Now expand the package body again and look what is displayed.
    Why? It is because SQL Developer handles words "Function", "Procedure" and "Loop" as keywords and according to them does the parsing.
    Another case
    CREATE OR REPLACE PACKAGE Test_Package1 AS
    gvc_const CONSTANT VARCHAR2(10) := 'xxx';
    TYPE Loop_rec IS RECORD(
      item1   LOOP.AREA%TYPE);
    PROCEDURE Test(p_RC OUT NUMBER,
                   p_ID IN NUMBER);
    END Test_Package1;Compile just this specification and try to expand it in the tree. Again, during parsing the package, SQL Developer takes the word "LOOP" into consideration and fails to parse the specification.
    There is exactly the same problem when you declare functions from external dll libraries in package body. Since there is no "END;" in this case, SQL Developer's parser fails...
    To me it seems you simply blindly took some keywords like "FUNCTION" and expect there will be some "END;" keyword corresponding with it.
    Can anyone have a look at this and finally fix it?

    Hi,
    Thanks for trying out SQL Developer 3.1 EA2 and providing a clear, reproducible test case for this issue. I logged an internal bug for it:
    Bug 13438696 - 3.1EA2: FORUM: CERTAIN KEYWORDS IN PKG BODY BLOCK MEMBERS FROM CONN VIEW TREE
    It seems the bug noted in the other forum thread you reference has been fixed, but really had nothing to do with problems discussed either here or there. That fix involved adding an Edit Body... item to the Package context menu in the Schema Browser, not displaying Package members correctly in the Connection view tree.
    Regards,
    Gary
    SQL Developer Team

  • Package body error

    Hi
    With the following line of code i am having problems with the following line of code ...
    sql := (
    ' IF INSERTING THEN '||CHR(10)||
    ' v_operation := ''INSERT''; '||CHR(10)||
    ' ELSIF UPDATING THEN '||CHR(10)||
    ' v_operation := ''UPDATE''; '||CHR(10)||
    ' ELSE '||CHR(10)||
    ' v_operation := ''DELETE''; '||CHR(10)||
    ' END IF; '||CHR(13));
    When I execute my package body I get an error with the above in my package ...
    any ideas why ?

    Bad variable name.
    ME_XE?declare
      2  sql long;
      3  begin
      4  null;
      5  end;
      6  /
    sql long;
    ERROR at line 2:
    ORA-06550: line 2, column 1:
    PLS-00103: Encountered the symbol "SQL" when expecting one of the following:
    begin function package pragma procedure subtype type use
    <an identifier> <a double-quoted delimited-identifier> form
    current cursor
    The symbol "<an identifier> was inserted before "SQL" to continue.
    Elapsed: 00:00:00.06
    ME_XE?declare
      2  wsql long;
      3  begin
      4  null;
      5  end;
      6  /
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.03
    ME_XE?
    {code}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Search Package Body for Keywords

    I would like to know if anyone has a query to search a package body for a particular word and then return all of the procedure names where that word (or words) are found. I am in the beginning stages of a 3-5 year upgrade/re-write project and just when I think that I have been given all of the requirements "they" come up with something else. Go figure! For instance I might need to find all of the procedures for a package or packages that contain the word product. Manually searching through all of my packages is very time consuming and I'm sure that someone out there has already written a query to do this.
    Any help will be greatly appreciated!
    Thanks!
    Randy

    >
    I would like to know if anyone has a query to search a package body for a particular word and then return all of the procedure names where that word (or words) are found. I am in the beginning stages of a 3-5 year upgrade/re-write project and just when I think that I have been given all of the requirements "they" come up with something else. Go figure! For instance I might need to find all of the procedures for a package or packages that contain the word product. Manually searching through all of my packages is very time consuming and I'm sure that someone out there has already written a query to do this.
    >
    A query? No
    Would you settle for Oracle supplied functionality that can probably provide all of that cross-reference information for you?
    As you can tell from all of the other replies it seems many, if not most, people are not familiar with PL/Scope, which was introduced in version 11.1 (you should always provide your 4 digit Oracle version).
    >
    PL/Scope is a compiler-driven tool that collects data about identifiers in PL/SQL source code at program-unit compilation time and makes it available in static data dictionary views. The collected data includes information about identifier types, usages (declaration, definition, reference, call, assigment) and the location of each usage in the source code.
    PL/Scope enables the development of powerful and effective PL/Scope source code browsers that increase PL/SQL developer productivity by minimizing time spent browsing and understanding source code.
    PL/Scope is intended for application developers, and will usually be used in the environment of a development database.
    >
    See Chapter 8 Using PL/Scope in the Advanced Appication Developer's Guide
    http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_plscope.htm
    >
    Specifying Identifier Collection
    By default, PL/Scope does not collect data for identifiers in the PL/SQL source program. To have PL/Scope collect data for all identifiers in the PL/SQL source program, including identifiers in package bodies, set the PL/SQL compilation parameter PLSCOPE_SETTINGS to 'IDENTIFIERS:ALL'.
    >
    Without knowing your actual needs or requirements I can't speculate on whether this will give you everything you are looking for.
    But don't reinvent the wheel without checking this out first.
    Basically just set the compilation parameter and recompile all of the code. Then there will be static dictionary views available with the cross-reference data.
    Even if you are not currently using 11g if I were you I would create an 11g sandbox with all of the objects and code (no data needed) just so you could use PL/Scope to get this cross-reference information.

  • Problem with merge using package (row)variable

    We're doing an ETL project, where we have to validate data coming from staging tables before inserting / updating them in our data tables.
    We use a validate function for this, in which we 'test' our mappings and business logic, and returns 'OK' if no errors were occured.This function is called in the WHERE clause, and populates a package row variable. From this variable, values are read in the insert / update statement, using a get function.
    The problem is that sometimes, with a data set with NO duplicate keys, we get an ORA-00001 error, and sometimes not.
    Does anyone have any idea why this error could occur ? We're on Oracle 9.2.0.5.0.
    For the demo mentioned below, the following statement fails , while it succeeds if we add 'and rownum < 11' to the where clause :
    merge into target_tab t
    using (select st.* from source_tab st where demo_pack.assign_var(st.attrib_1, st.attrib_2, st.attrib_3) = 'OK') s
    on (t.attrib_1 = s.attrib_1 and
    t.attrib_2 = s.attrib_2)
    when matched then update
    set t.attrib_3 = demo_pack.get_attrib('ATTRIB_3')
    when not matched then
    insert(attrib_1, attrib_2, attrib_3)
    values (demo_pack.get_attrib('ATTRIB_1'), demo_pack.get_attrib('ATTRIB_2'), demo_pack.get_attrib('ATTRIB_3'));
    Can anyone explain to me why this statement sometimes fails, and other times not ?
    Thanks in advance .
    demo tables / packages :
    create table source_tab
    attrib_1 varchar2(30),
    attrib_2 varchar2(30),
    attrib_3 varchar2(200)
    create table target_tab
    attrib_1 varchar2(30) not null,
    attrib_2 varchar2(30) not null,
    attrib_3 varchar2(200),
    constraint pk_target_tab primary key(attrib_1, attrib_2)
    insert into source_tab
    select table_name, column_name, data_type
    from user_tab_columns;
    commit;
    create or replace package demo_pack as
    function assign_var(p_attrib_1 in target_tab.attrib_1%type,
    p_attrib_2 in target_tab.attrib_2%type,
    p_attrib_3 in target_tab.attrib_3%type) return varchar2;
    function get_attrib(p_name in varchar2) return varchar2;
    end;
    create or replace package body demo_pack as
    g_rec target_tab%rowtype;
    function assign_var(p_attrib_1 in target_tab.attrib_1%type,
    p_attrib_2 in target_tab.attrib_2%type,
    p_attrib_3 in target_tab.attrib_3%type) return varchar2 is
    begin
    g_rec.attrib_1 := p_attrib_1;
    g_rec.attrib_2 := p_attrib_2;
    g_rec.attrib_3 := p_attrib_3;
    return 'OK';
    end;
    function get_attrib(p_name in varchar2) return varchar2 is
    l_return varchar2(200);
    begin
    if p_name = 'ATTRIB_1' then
    l_return := g_rec.attrib_1;
    elsif p_name = 'ATTRIB_2' then
    l_return := g_rec.attrib_2;
    elsif p_name = 'ATTRIB_3' then
    l_return := g_rec.attrib_3;
    end if;
    return l_return;
    end;
    end;
    /

    It's not necessarily that the problem is within your package code. As long as UNIQUE constraint exists on DEST table, any MERGE statement may fail with ORA-00001 due to concurrent updates and inserts taking place.
    Of course, it's just my guess but consider the following scenario (three sessions modify DEST table in parallel – and to keep this example clear, I put their commands in chronological order):
    S#1>  create table dest(x primary key, y) as
      2   select rownum, rownum
      3     from dual
      4  connect by level <= 5;
    Table created.
    S#1>  create table src(x, y) as
      2   select rownum + 1, rownum + 1
      3     from dual
      4  connect by level <= 5;
    Table created.
    S#1> select * from src;
             X          Y
             2          2
             3          3
             4          4
             5          5
             6          6
    S#1> select * from dest;
             X          Y
             1          1
             2          2
             3          3
             4          4
             5          5
    S#2> -- Now, session #2 will update one row in DEST table
    S#2> update dest
      2     set y = 40
      3   where x = 4;
    1 row updated.
    S#2> select * from dest;
             X          Y
             1          1
             2          2
             3          3
             4         40
             5          5
    S#1> -- Session #1 issues the following MERGE:
    S#1> merge into dest d
      2  using (select * from src) s
      3     on (s.x = d.x)
      4   when matched then update set d.y = s.y
      5   when not matched then insert (d.x, d.y)
      6        values (s.x, s.y);
    -- At this point, session #1 becomes blocked as it can not modify row locked by session #2
    S#3> -- Now, session #3 inserts new row into DEST and commits.
    S#3> -- MERGE in session #1 is still blocked.
    S#3> insert into dest values (6, 6);
    1 row created.
    S#3> select * from dest;
             X          Y
             1          1
             2          2
             3          3
             4          4
             5          5
             6          6
    6 rows selected.
    S#3> commit;
    Commit complete.
    S#2> -- Session #2 rolls back its UPDATE.
    S#2> rollback;
    Rollback complete.
    -- Finally, session #1 is getting unblocked, but...
    merge into dest d
    ERROR at line 1:
    ORA-00001: unique constraint (MAX.SYS_C0032125) violated
    S#1>Hope this helps,
    Andrew.

  • How do I view a FUNCTION within a Package Body

    I can see the FUNCTION being executed within the Package...
    FUNCTION Stop_Refresh_AsBilled
    RETURN Number;
    And within Oracle SQL Developer and using the Connection and "Packages" part of the Schema, I see the Function Name. However, when I <Double-Click> on the FUNCTION Name within the Schema, it is taking me to where the FUNCTION is executed within the Package and NOT to the PL/SQL Code that actually makes up the FUNCTION.
    Am I missing something here??? Maybe in my Preferences??? How can I drill down further to actually find the FUNCTION Definition and PL/SQL Code that makes up the FUNCTION within the Package Body???
    I can bring up the Package Body and Search on the FUNCTION that way. I'm hoping there is an easier way however to drill down to the actual PL/SQL Code that makes up the FUNCTION.
    I hope I am being clear in my explanation here.
    Thanks for your review and I am hopeful for a reply.
    PSULionRP

    Jim, opening the body node to see all functions and procedures sometimes does not work in 3.0
    I have many packages generated by Feuerstien's CodeGen utility. The Query package appears just fine with every function and procedure appearing as expected in both header and body nodes. However, the Change Package fails miserably. Header shows all functions and procedures fine, but the body node only shows the top private declarations of variables and types. Not one function or procedure appears in the expanded node.
    The only thing I can figure is that the Change package of about 30 named items has many of the same name+ with overloaded parameters. I think SQL Dev is having problems parsing the names in the body even though it does fine with the names in the header of the package--perhaps because of many private variables and PRAGMA's declared at the top of the body.
    Both packages have about 30 functions, but the Change package body has over 2000 lines while the Query package has fewer than 500.
    Just adding to the mystery--but I think it merits a bug report (gotta figure out where to report it now).

  • Are PL/SQL Package Body Constants in Shared Area or Private Area

    Based on this it not clear to me if PL/SQL Package Body Constants are stored in shared area or private area.
    http://docs.oracle.com/cd/B28359_01/server.111/b28318/memory.htm
    "PL/SQL Program Units and the Shared Pool
    Oracle Database processes PL/SQL program units (procedures, functions, packages, anonymous blocks, and database triggers) much the same way it processes individual SQL statements. Oracle Database allocates a shared area to hold the parsed, compiled form of a program unit. Oracle Database allocates a private area to hold values specific to the session that runs the program unit, including local, global, and package variables (also known as package instantiation) and buffers for executing SQL. If more than one user runs the same program unit, then a single, shared area is used by all users, while each user maintains a separate copy of his or her private SQL area, holding values specific to his or her session.
    Individual SQL statements contained within a PL/SQL program unit are processed as described in the previous sections. Despite their origins within a PL/SQL program unit, these SQL statements use a shared area to hold their parsed representations and a private area for each session that runs the statement."
    I am also curious what are the fine grained differences from a memory and performance perspective (multi-session) for the two examples below. Is one more efficient?
    Example 1.
    create or replace
    package body
    application_util
    as
    c_create_metadata constant varchar2(6000) := ...
    procedure process_xxx
    as
    begin
    end process_xxx;
    end application_util;
    vs.
    Example 2.
    create or replace
    package body
    application_util
    as
    procedure process_xxx
    as
    c_create_metadata constant varchar2(6000) := ...
    begin
    end process_xxx;
    end application_util;

    >
    What i am asking is fairly granular, so here it is again, let's assume latest version of oracle..
    In a general sense, is the runtime process able to manage memory more effectively in either case, one even slightly more performant, etc
    ie does example 1 have different memory management characteristics than example 2.
    Specifically i am talking about the memory allocation and unallocation for the constant varchar2(6000)
    Ok, a compiler's purpose is basically to create an optimized execution path from source code.
    The constant varchar2(6000) := would exist somewhere in the parse tree/execution path (this is stored in the shared area?).
    I guess among the things i'm after is
    1) does each session use space needed for an additional varchar2(6000) or does runtime processor simply point to the constant string in the parse tree (compiled form which is shared).
    2) if each session requires allocation of space needed for an additional varchar2(6000), then for example 1 and example 2
    at what point does the constant varchar allocation take place and when is the memory unallocated.
    Basically does defining the constant within the procedure have different memory characteristics than defining the constant at the package body level?
    >
    Each 'block' or 'subprogram' has a different scope. So the 'constant' defined in your example1 is 'different' (and has a different scope) than the 'constant' defined in example2.
    Those are two DIFFERENT objects. The value of the 'constant' is NOT assigned until control passes to that block.
    See the PL/SQL Language doc
    http://docs.oracle.com/cd/E14072_01/appdev.112/e10472/fundamentals.htm#BEIJHGDF
    >
    Initial Values of Variables and Constants
    In a variable declaration, the initial value is optional (the default is NULL). In a constant declaration, the initial value is required (and the constant can never have a different value).
    The initial value is assigned to the variable or constant every time control passes to the block or subprogram that contains the declaration. If the declaration is in a package specification, the initial value is assigned to the variable or constant once for each session (whether the variable or constant is public or private).
    >
    Perhaps this example code will show you why, especially for the second example, a 'constant' is not necessarily CONSTANT. ;)
    Here is the package spec and body
    create or replace package pk_test as
      spec_user varchar2(6000);
      spec_constant varchar2(6000) := 'dummy constant';
      spec_constant1 constant varchar2(6000) := 'first constant';
      spec_constant2 constant varchar2(6000) := 'this is the second constant';
      spec_constant3 constant varchar2(6000) := spec_constant;
      procedure process_xxx;
      procedure change_constant;
    end pk_test;
    create or replace package body pk_test as
    procedure process_xxx
    as
      c_create_metadata constant varchar2(6000) := spec_constant;
    begin
      dbms_output.put_line('constant value is [' || c_create_metadata || '].');
    end process_xxx;
    procedure change_constant
    as
    begin
      spec_constant := spec_constant2;
    end change_constant;
    begin
      dbms_output.enable;
      select user into spec_user from dual;
      spec_constant := 'User is ' || spec_user || '.';
    end pk_test;The package init code sets the value of a packge variable (that is NOT a constant) based on the session USER (last code line in package body).
    The 'process_xxx' procedure gets the value of it's 'constant from that 'non constant' package variable.
      c_create_metadata constant varchar2(6000) := spec_constant;The 'change_constant' procedure changes the value of the package variable used as the source of the 'process_xxx' constant.
    Now the fun part.
    execute the 'process_xxx' procedure as user SCOTT.
    SQL> exec pk_test.process_xxx;
    constant value is [User is SCOTT.].Now execute 'process_xxx' as another user
    SQL> exec pk_test.process_xxx;
    constant value is [User is HR.].Now exec the 'change_constant' procedure.
    Now exec the 'process_xxx' procedure as user SCOTT again.
    SQL> exec pk_test.process_xxx;
    constant value is [this is the second constant].That 'constant' defined in the 'process_xxx' procedure IS NOT CONSTANT; it now has a DIFFERENT VALUE.
    If you exec the procedure as user HR it will still show the HR constant value.
    That should convince you that each session has its own set of 'constant' values and so does each block.
    Actually the bigger memory issue is the one you didn't ask about: varchar2(6000)
    Because you declared that using a value of 6,000 (which is 2 ,000 or more) the actual memory allocation not done until RUN TIME and will only use the actual amount of memory needed.
    That is, it WILL NOT pre-allocate 6000 bytes. See the same doc
    http://docs.oracle.com/cd/E14072_01/appdev.112/e10472/datatypes.htm#CJAEDAEA
    >
    Memory Allocation for Character Variables
    For a CHAR variable, or for a VARCHAR2 variable whose maximum size is less than 2,000 bytes, PL/SQL allocates enough memory for the maximum size at compile time. For a VARCHAR2 whose maximum size is 2,000 bytes or more, PL/SQL allocates enough memory to store the actual value at run time. In this way, PL/SQL optimizes smaller VARCHAR2 variables for performance and larger ones for efficient memory use.
    For example, if you assign the same 500-byte value to VARCHAR2(1999 BYTE) and VARCHAR2(2000 BYTE) variables, PL/SQL allocates 1999 bytes for the former variable at compile time and 500 bytes for the latter variable at run time.
    >
    So when you have variables and don't know how much space is really needed do NOT do this:
    myVar1 VARCHAR2(1000);
    myVar2 VARCHAR2(1000);
    myVar3 VARCHAR2(1000);The above WILL allocate 3000 bytes of expensive memory even if it those variables are NEVER used.
    This may look worse but, as the doc states, it won't really allocate anything if those variables are not used. And when they are used it will only use what is needed.
    myVar1 VARCHAR2(2000);
    myVar2 VARCHAR2(2000);
    myVar3 VARCHAR2(2000);

  • User in Package Body changing

    Hello,
    When i create a package body, and change the user to the default and save...
    It continually switches back to 'User3'. If I open the 'properties', I see
    the correct user is set, however when I 'edit' the body,
    in the declaration it always reverts back to:
    CREATE OR REPLACE PACKAGE BODY User3.MYPKG_PKG AS ...
    even if i change that and save.. next time it opens I see the same thing..
    I have the Default user set correctly in the prefs.. anything else i can try?
    thanks!
    -chris

    Hi Chris,
    It seems there is a problem that if there is a tab in the main window showing the text of the Package or the Package Body, then on doing a File/Save, the owner is reset to the owner shown in that text.
    One of these tabs is set up whenever a new Package or Package Body is created.
    Unfortunately this text does not get updated if the Properties dialog is subsequently used to change the User.
    To get round this you should close the tabs for the Package and the Package Body before using the Properties dialog to change the User. (If you then wish to reopen them, you can do this by selecting Edit from the menu that appears if you right-click over the Package or Package Body.)
    There is a second problem that the Default User identified in the Preferences is ignored when a new Package is created.
    I have logged bugs on both these problems.
    David

  • SQL Queries don’t recognize Package member variables.

    Hi,
    I have a package defined like this:
    CREATE OR REPLACE PACKAGE PROD.PKG_BSYS_COMMON
    AS
    MAX_RETURN_ROWS NUMBER(6) :=1000;
    END PKG_BSYS_COMMON;
    The problem is that I cannot use MAX_RETURN_ROWS in my SQL queries:
    SELECT
    FROM
    CLIENT
    WHERE
    ROWNUM < PROD.PKG_BSYS_COMMON.MAX_RETURN_ROWS
    Is there any way to use that package member variable in my queries?
    This is a simplified explanation of our problem and it is very important for our business to avoid hardcoding constants in queries and define all of them in a central location. Is there a better way doing this?
    Any help would be appreciated,
    Alan

    CREATE OR REPLACE PACKAGE PKG_BSYS_COMMON
    AS
    function max_return_rows return number ;
    END PKG_BSYS_COMMON;
    CREATE OR REPLACE PACKAGE body PKG_BSYS_COMMON  as
    function max_return_rows return number is
    begin
    return(1000);
    end;
    end PKG_BSYS_COMMON;
    select pkg_bsys_common.max_return_rows from dual;
    MAX_RETURN_ROWS
               1000                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • How to find timestamp of packege/package body compiled in last 15 days

    Hi all,
    I would like to find the time stamp of package/package body compiled in the last 15 days.
    Is there any feature, which will log all the compilation time stamp of a particular package or package body.
    If so, please provide the query.
    version : Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production
    Thanks
    Raghu

    You can check the same from ALL_OBJECTs/USER_OBJECTS/DBA_OBJECTS.
    In this views,
    column CREATED always shows its created date & time.
    LAST_DDL_TIME always shows last compiled time also it change if you run create or replace
    TIMESTAMP will give you last change i.e. create OR replace time,
    create  package temp_pkg (v number;
                         sp_procedure());
    select object_name,object_type, created, last_ddl_time, timestamp from all_objects
    where object_type in ('PACKAGE','PACKAGE BODY')and object_name ='TEMP_PKG';
    OBJECT_NAME           OBJECT_TYPE                CREATED                   LAST_DDL_TIME             TIMESTAMP
    TEMP_PKG             PACKAGE                    11/12/2012 6:07:18 PM     11/12/2012 6:07:18 PM     2012-11-12:18:07:18
    alter package temp_pkg compile;
    select object_name,object_type, created, last_ddl_time, timestamp from all_objects
    where object_type in ('PACKAGE','PACKAGE BODY')and object_name ='TEMP_PKG';
    OBJECT_NAME           OBJECT_TYPE                CREATED                   LAST_DDL_TIME             TIMESTAMP
    TEMP_PKG             PACKAGE                    11/12/2012 6:07:18 PM     11/12/2012 6:08:19 PM     2012-11-12:18:07:18
    create  or replace package temp_pkg (v number;
                         sp_procedure());
    select object_name,object_type, created, last_ddl_time, timestamp from all_objects
    where object_type in ('PACKAGE','PACKAGE BODY')and object_name ='TEMP_PKG';   
    OBJECT_NAME           OBJECT_TYPE                CREATED                   LAST_DDL_TIME             TIMESTAMP
    TEMP_PKG             PACKAGE                    11/12/2012 6:07:18 PM     11/12/2012 6:10:00 PM     2012-11-12:18:10:00                
    alter package temp_pkg compile;
    select object_name,object_type, created, last_ddl_time, timestamp from all_objects
    where object_type in ('PACKAGE','PACKAGE BODY')and object_name ='TEMP_PKG';
    OBJECT_NAME           OBJECT_TYPE                CREATED                   LAST_DDL_TIME             TIMESTAMP
    TEMP_PKG             PACKAGE                    11/12/2012 6:07:18 PM     11/12/2012 6:11:07 PM     2012-11-12:18:10:00For packages/package body compiled/created/replaced in last 15 days you can check with below query.
    select object_name,object_type, created, last_ddl_time, timestamp
    from all_objects
    where object_type in ('PACKAGE','PACKAGE BODY')and (sysdate-last_ddl_time)<=15 ;Edited by: myOra_help on Nov 12, 2012 6:45 PM

  • Please help with package body

    Hi This is my package veriable and body is created, but when I try to create a package body, it shows error
    {CREATE or replace PACKAGE crime_type AS
       FUNCTION tot_no_of_crime(CRIME_TYPE_ID NUMBER,CRIME_TYPE_DESC VARCHAR2, REPORTED_CRIME_ID NUMBER,DATE_REPORTED DATE,
    CRIME_POSTCODE VARCHAR2,DATE_CLOSED DATE,FK1_CRIME_TYPE_ID NUMBER,FK2_STATION_ID VARCHAR2)
          RETURN NUMBER;
       FUNCTION create_CRIME_TYPE(CRIME_TYPE_DESC VARCHAR2, CRIME_TYPE_ID NUMBER)
          RETURN NUMBER;
       PROCEDURE remove_PL_CRIME_TYPE1(CRIME_TYPE_ID NUMBER);
       PROCEDURE remove_PL_REPORTED_CRIME1(REPORTED_CRIME_ID NUMBER);
       PROCEDURE increase_CRIME_TYPE(CRIME_TYPE_ID NUMBER,CRIME_TYPE_DESC VARCHAR2);
       PROCEDURE increase_REPORTED_CRIME( CRIME_TYPE_ID NUMBER, REPORTED_CRIME_incr NUMBER);
          no_REPORTED_CRIME EXCEPTION;
          no_CRIME_TYPE EXCEPTION;
    END crime_type;}
    package body is
    {CTFUNCTION initialise_crime_types
    return NUMBER is
    total number;
    begin
          select count(*) into total from PL_CRIME_TYPE1;
          return(total);
    End;
    FUNCTION REPORTED_CRIME
       (REPORTED_CRIME_ID NUMBER,
      DATE_REPORTED  DATE,
        CRIME_POSTCODE VARCHAR2 ,
        CRIME_STATUS VARCHAR2 ,
        DATE_CLOSED DATE ,
        FK1_CRIME_TYPE_ID NUMBER,
        FK2_STATION_ID VARCHAR2)
    RETURN NUMBER IS
       new_reported_crime_id NUMBER(3);
    BEGIN
       SELECT crimetypeseq.NEXTVAL
          INTO new_reported_crime_id
          FROM DUAL;
       INSERT INTO PL_REPORTED_CRIME1(REPORTED_CRIME_ID, DATE_REPORTED, CRIME_POSTCODE, CRIME_STATUS, DATE_CLOSED, FK1_CRIME_TYPE_ID, FK2_STATION_ID)
          VALUES (REPORTED_CRIME_ID, DATE_REPORTED, CRIME_POSTCODE, CRIME_STATUS, DATE_CLOSED, FK1_CRIME_TYPE_ID, FK2_STATION_ID);
             tot_reported_crimes := tot_reported_crimes + 1;
       RETURN(new_CRIME_TYPE_ID);
    END;
    FUNCTION create_CRIME_TYPE(CRIME_TYPE_DESC VARCHAR2)
           RETURN NUMBER IS
          new_crime_type_id NUMBER(38,0);
       BEGIN
          SELECT  crimetypeseq.NEXTVAL;
             INTO new_crime_type_id
             FROM DUAL;
          INSERT INTO PL_CRIME_TYPE1
             VALUES (CRIME_TYPE_ID CRIME_TYPE_DESC );
                tot_crime_types := tot_crime_types + 1;
          RETURN(new_reported_crime_id);
       END;
    PROCEDURE remove_crime_types(crime_type_id NUMBER) IS
       BEGIN
          DELETE FROM PL_CRIME_TYPE1
          WHERE PL_CRIME_TYPE1.crime_type_id = remove_PL_CRIME_TYPE1.crime_type_id;
             tot_no_of_crimes := tot_no_of_crimes - 1;
       END;
    PROCEDURE remove_reported_crimes(reported_crime_id NUMBER) IS
       BEGIN
          DELETE FROM PL_REPORTED_CRIME1
          WHERE PL_REPORTED_CRIME1 .reported_crime_id = remove_PL_REPORTED_CRIME1.reported_crime_id;
             tot_reported_crimes := tot_reported_crimes - 1;
          SELECT COUNT(*)
             INTO tot_crime_types
             FROM PL_CRIME_TYPE1;
    End;
    PROCEDURE increase_crime_type(CRIME_TYPE_ID NUMBER,CRIME_TYPE_DESC VARCHAR2) IS
       curr_ crime_typeNUMBER(7,2);
       BEGIN
          SELECT crime_type
          INTO curr_crime_type
          FROM PL_CRIME_TYPE1
          WHERE PL_CRIME_TYPE1.crime_type_id = increase_crime_type.crime_type_id;
          IF curr_crime_type IS NULL
             THEN RAISE no_crime_type;
          ELSE
             UPDATE PL_CRIME_TYPE1
             SET crime_type = crime_type + crime_type_incr
             WHERE crime_type_id = crime_type_id;
          END IF;
       END;
    PROCEDURE increase_reported_crime(CRIME_TYPE_ID NUMBER, REPORTED_CRIME_incr NUMBER) IS
          curr_reported_crime NUMBER(7,2);
       BEGIN
          SELECT reported_crime
          INTO curr_reported_crime
          FROM PL_REPORTED_CRIME1
          WHERE PL_REPORTED_CRIME1.crime_type_id = increase_reported_crime.crime_type_id;
          IF curr_reported_crime IS NULL
             THEN RAISE no_reported_crime;
          ELSE
             UPDATE PL_REPORTED_CRIME1
             SET reported_crime = reported_crime + reported_crime_incr;
          END IF;
       END;
    BEGIN
    select count(*) into tot_crime_types from PL_CRIME_TYPE1;
          select count(*) into tot_reported_crimes from PL_REPORTED_CRIME1;
    tot_crime_types := initialise_crime_types();
    tot_reported_crimes:= initialise_tot_reported_crimes();
    END;}

    Ganesh Ji Namaste
    I have changed my Package variable. My new veriable is
    {CREATE or replace PACKAGE crime_type AS
       FUNCTION tot_no_of_crime_type(CRIME_TYPE_ID NUMBER,CRIME_TYPE_DESC VARCHAR2)
          RETURN NUMBER;
       FUNCTION CREATE_REPORTED_CRIME(REPORTED_CRIME_ID NUMBER,DATE_REPORTED DATE,CRIME_POSTCODE VARCHAR2,CRIME_STATUS VARCHAR2,DATE_CLOSED DATE,FK1_CRIME_TYPE_ID NUMBER,FK2_STATION_ID NUMBER)
          RETURN NUMBER;
       PROCEDURE remove_PL_CRIME_TYPE1(CRIME_TYPE_ID NUMBER);
       PROCEDURE remove_PL_REPORTED_CRIME1(REPORTED_CRIME_ID NUMBER);
       PROCEDURE increase_CRIME_TYPE(CRIME_TYPE_ID NUMBER,CRIME_TYPE_DESC VARCHAR2);
       PROCEDURE increase_REPORTED_CRIME( CRIME_TYPE_ID NUMBER, REPORTED_CRIME_incr NUMBER);
          no_REPORTED_CRIME EXCEPTION;
          no_CRIME_TYPE EXCEPTION;
    END crime_type;}
    and my body package is
    {CREATE OR REPLACE PACKAGE BODY crime_type AS
       tot_crime_types NUMBER;
       tot_reported_crimes NUMBER;
    FUNCTION initialise_crime_types
    return number is
    total number;
    begin
          select count(*) into total from PL_CRIME_TYPE1;
          return(total);
    End;
    FUNCTION initialise_reported_crimes
    return number is
    total number;
    begin
          select count(*) into total from PL_REPORTED_CRIME1;
          return(total);
    End;
    FUNCTION tot_no_of_crime_type
       (CRIME_TYPE_ID NUMBER,
        CRIME_TYPE_DESC VARCHAR2)
    RETURN NUMBER IS
       new_crime_type_id NUMBER(38,0);
    BEGIN
       SELECT crimetypeseq.NEXTVAL
          INTO new_crime_type_id
          FROM DUAL;
       INSERT INTO PL_CRIME_TYPE1(CRIME_TYPE_ID, CRIME_TYPE_DESC)
          VALUES (new_CRIME_TYPE_ID, CRIME_TYPE_DESC);
             tot_crime_types := tot_crime_types + 1;
       RETURN(new_CRIME_TYPE_ID);
    END;
    FUNCTION CREATE_REPORTED_CRIME(REPORTED_CRIME_ID NUMBER,DATE_REPORTED DATE,CRIME_POSTCODE VARCHAR2,CRIME_STATUS VARCHAR2,DATE_CLOSED DATE,FK1_CRIME_TYPE_ID NUMBER,FK2_STATION_ID NUMBER)
       RETURN NUMBER IS
          new_reported_crime_id NUMBER(38,0);
       BEGIN
          SELECT reportedcrimeseq.NEXTVAL
             INTO new_reported_crime_id
             FROM dual;
          INSERT INTO PL_REPORTED_CRIME1
             VALUES (new_reported_crime_id,REPORTED_CRIME_ID,DATE_REPORTED,CRIME_POSTCODE,CRIME_STATUS,DATE_CLOSED,FK1_CRIME_TYPE_ID,FK2_STATION_ID);
                tot_reported_crimes := tot_reported_crimes + 1;
          RETURN(new_reported_crime_id);
       END;
    PROCEDURE remove_crime_types(crime_type_id NUMBER) IS
       BEGIN
          DELETE FROM PL_CRIME_TYPE1
          WHERE PL_CRIME_TYPE1.crime_type_id = remove_PL_CRIME_TYPE1.crime_type_id;
             tot_crime_types := tot_crime_types - 1;
       END;
    PROCEDURE remove_reported_crimes(reported_crime_id NUMBER) IS
       BEGIN
          DELETE FROM PL_REPORTED_CRIME1
          WHERE PL_REPORTED_CRIME1 .reported_crime_id = remove_PL_REPORTED_CRIME1.reported_crime_id;
             tot_reported_crimes := tot_reported_crimes - 1;
          SELECT COUNT(*)
             INTO tot_crime_types
             FROM PL_CRIME_TYPE1;
    End;
    PROCEDURE increase_crime_type(CRIME_TYPE_ID NUMBER,CRIME_TYPE_DESC VARCHAR2) IS
       curr_ crime_typeNUMBER(38,0);
       BEGIN
          SELECT crime_type
          INTO curr_crime_type
          FROM PL_CRIME_TYPE1
          WHERE PL_CRIME_TYPE1.crime_type_id = increase_crime_type.crime_type_id;
          IF curr_crime_type IS NULL
             THEN RAISE no_crime_type;
          ELSE
             UPDATE PL_CRIME_TYPE1
             SET crime_type = crime_type + crime_type_incr
             WHERE crime_type_id = crime_type_id;
          END IF;
       END;
    PROCEDURE increase_reported_crime(CRIME_TYPE_ID NUMBER, REPORTED_CRIME_incr NUMBER) IS
          curr_reported_crime NUMBER(7,2);
       BEGIN
          SELECT reported_crime
          INTO curr_reported_crime
          FROM PL_REPORTED_CRIME1
          WHERE PL_REPORTED_CRIME1.crime_type_id = increase_reported_crime.crime_type_id;
          IF curr_reported_crime IS NULL
             THEN RAISE no_reported_crime;
          ELSE
             UPDATE PL_REPORTED_CRIME1
             SET reported_crime = reported_crime + reported_crime_incr;
          END IF;
       END;
    BEGIN
    select count(*) into tot_crime_types from PL_CRIME_TYPE1;
          select count(*) into tot_reported_crimes from PL_REPORTED_CRIME1;
    tot_crime_types := initialise_crime_types();
    tot_reported_crimes:= initialise_reported_crimes();
    END;}
    Could You please check is that correct or not?
    Thanks in advance for your time and co-operation
    Rubel Roy

Maybe you are looking for

  • How to get corresponding invoices of a GR document...

    Hello Experts, Is there a way to get the corresponding invoices of a goods receipt document? I know they can be fetched from table EKBE but the only link I think is the PO number which results with a display error on my report. Are there any FMs or B

  • Some of my fonts are not showing in my browser, could it be due to font book?

    Hi All of a sudden I noticed two websites which I commonly use, not displaying some of its fonts correctly. At first I thought it was just the browsers fault, firefox to be specific, but after checking Safari. I found that Safari was displaying the f

  • Will my tv (sharp aquos lc-32px5x) work with apple tv?

    I'm wondering if my tv will work for apple tv so I can stream my iPad. Thanks for the help. (I don't think it's hd, but it has hdmi cable inputs)

  • How to clear the contents of table control

    Hi All,           How to clear the contents that are present in a Table control. If there is any code Please Let me know. I will assign full marks to the correct code. Pradeep Kumar Kota.

  • PR Qty is merged eventhough Ind./Coll=1

    Hi All, MRP (MD51) generated PR quantity is merged eventhough Ind./Collective indicator is set to 1. Under one WBS element, there is a component ex: ABC, which falls two times. Why a single PR is generated with merged quantity? Why not two PR is gene