I am trying to compile an Oracle package that my colleague left to me. However, the package spec. contains some functions that may not be built in my Oracle environment.
create or replace PACKAGE AAA IS
g_session VARCHAR2(400) := v('SESSION');
g_user VARCHAR2(400) := v('APP_USER');
PROCEDURE p_1;
END AAA;
When I try to compile the package spec in Oracle developer, I states
'V' must be declared.
Since the colleague that left me this code is no longer available, I have no idea of how to compile them.
The v function is meaningful in Apex environment; it'll return the value of the parameter you pass to it. In your example, that would be something like this:
v('SESSION') = 32604633949883 --> session ID
v('APP_USER') = LITTLEFOOT --> user logged to Apex
Apart from Apex environment, the v function works from your named PL/SQL stored procedures, packages and such.
As you aren't capable of compiling that code, it seems that there's no Apex installed in the database that contains that package. Is there? If not, well, you won't be able to compile it so you can:
install Apex, or
remove the v function calls from your code
Related
My package header code looks like this:
CREATE OR REPLACE PACKAGE INST_PKG IS
...
FUNCTION Check_View (
view_name_ IN VARCHAR2 ) RETURN BOOLEAN;
PRAGMA restrict_references (Check_View, WNDS);
...
END INST_PKG;
And the body of the function is defined as follows:
CREATE OR REPLACE PACKAGE BODY INST_PKG IS
....
FUNCTION View_Exist (
view_name_ IN VARCHAR2 ) RETURN BOOLEAN
IS
ck_ NUMBER := 0;
CURSOR check_view IS
SELECT 1
FROM user_views uv
WHERE uv.view_name = upper(view_name_);
BEGIN
OPEN check_view;
FETCH check_view INTO ck_;
IF check_view%FOUND THEN
CLOSE check_view;
RETURN true;
ELSE
CLOSE check_view;
RETURN false;
END IF;
END View_Exist;
....
END INST_PKG;
I get an error message which reads as follows, when I try to compile the package body:
Compilation errors for PACKAGE BODY INST_PKG
Error: PLS-00452: Subprogram 'VIEW_EXIST' violates its associated pragma
Line: 684
Text: FUNCTION View_Exist (
Clearly, my pragma of "Write No Database State" is not violated, as there are no DML statements in the function. Has anyone seen such behaviour before?
Of course, I could drop the Pragma reference, but that would kind of defeat the purpose.
Worthy of note:
My database has been exported from an Oracle 10g instance, and has been re-imported to 12c. (This is an upgrade test, as you might imagine). Hence I get the above error on Oracle 12c.
I have tried to drop and re-create the package, but that doesn't seem to change things.
I have a feeling that there may be a library reference somewhere that has been imported in error, because when I drop the package, the same error comes up in another package, which contains a function of the same name. But when I re-create the INST_PKG, the second package compiles fine, almost as though the problem in the first package is masking it from being flagged in the second.
It emerges from the link you showed, that the issue is a result of a bug in USER_VIEWS (Oracle forgot to associate PRAGMA restrict_references with NO_ROOT_SW_FOR_LOCAL).
In this case you can be certain that your function doesn't violate WNDS assertion (doesn't write to the database), therefore just use TRUST option to disable assertions validation during compilation:
PRAGMA restrict_references (Check_View, WNDS, TRUST);
Thanks for pointing me in the right direction #MuhammadMuzzam. The problem is user_views has some references which apparently violate Pragma in Oracle 12.
Seems to be an known issue:
https://community.oracle.com/thread/3650610?start=0&tstart=0
i try to get some records from DB Package (ORTAK.MERNIS) using its function (GETMERNISINFO(v_var number)) into PLL package type (MERNISLIB.MERNIS_USER).
But I ve a trouble with sending parameter to db package function (:TCK). It throws ORA-01008 : Not all variables bound
If I set function parameter statically (ORTAK.MERNIS.GETMERNISINFO(12345678)), it works as expected.
I use that code in Oracle Forms 6i
Any Ideas?
declare
MUSER MERNISLIB.MERNIS_USER;
begin
SELECT TCK,ADI,SOYADI INTO MUSER from table(cast(ORTAK.MERNIS.GETMERNISINFO(:TCK) as ORTAK.TCKTABLE));
:ADI := MUSER.ADI;
:SOYADI := MUSER.SOYADI;
end;
Looks like tck is coming from a text input item on the form. Can you try and fully qualify it as :block_name.item_name.
A library can't see the form items :ADI and :SOYADI because there is no guarantee the form the library is attached to will have them.
Use the COPY and NAME_IN functions to populate, or read form block items in a library procedure.
I am using oracle 10g and toad 11.5. I am trying to call an api from an anonymous block.
If I recompile the api after adding dbms_output.put_line and then try to execute the anonymous block, it shows error as:
"ORA-06508: PL/SQL: could not find program unit being called".
However if I end current session and open a new session, then the anonymous block will execute with out the error.
Due to this issue, i am made to reconnect the session everytime i make a change to API.
Can anyone help if this issue can be resolved by making any configurations in toad or database level.
I suspect you're only reporting the last error in a stack like this:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "schema.package" has been invalidated
ORA-04065: not executed, altered or dropped package body "schema.package"
ORA-06508: PL/SQL: could not find program unit being called: "schema.package"
If so, that's because your package is stateful:
The values of the variables, constants, and cursors that a package
declares (in either its specification or body) comprise its package
state. If a PL/SQL package declares at least one variable, constant,
or cursor, then the package is stateful; otherwise, it is stateless.
When you recompile the state is lost:
If the body of an instantiated, stateful package is recompiled (either
explicitly, with the "ALTER PACKAGE Statement", or implicitly), the
next invocation of a subprogram in the package causes Oracle Database
to discard the existing package state and raise the exception
ORA-04068.
After PL/SQL raises the exception, a reference to the package causes
Oracle Database to re-instantiate the package, which re-initializes
it...
You can't avoid this if your package has state. I think it's fairly rare to really need a package to be stateful though, so you should revisit anything you have declared in the package, but outside a function or procedure, to see if it's really needed at that level. Since you're on 10g though, that includes constants, not just variables and cursors.
But the last paragraph from the quoted documentation means that the next time you reference the package in the same session, you won't get the error and it will work as normal (until you recompile again).
seems like opening a new session is the key.
see this answer.
and here is an awesome explanation about this error
Based on previous answers. I resolved my issue by removing global variable at package level to procedure, since there was no impact in my case.
Original script was
create or replace PACKAGE BODY APPLICATION_VALIDATION AS
V_ERROR_NAME varchar2(200) := '';
PROCEDURE APP_ERROR_X47_VALIDATION ( PROCESS_ID IN VARCHAR2 ) AS BEGIN
------ rules for validation... END APP_ERROR_X47_VALIDATION ;
/* Some more code
*/
END APPLICATION_VALIDATION; /
Rewritten the same without global variable V_ERROR_NAME and moved to procedure under package level as
Modified Code
create or replace PACKAGE BODY APPLICATION_VALIDATION AS
PROCEDURE APP_ERROR_X47_VALIDATION ( PROCESS_ID IN VARCHAR2 ) AS
**V_ERROR_NAME varchar2(200) := '';**
BEGIN
------ rules for validation... END APP_ERROR_X47_VALIDATION ;
/* Some more code
*/
END APPLICATION_VALIDATION; /
I recompiled the package specification, even though the change was only in the package body. This resolved my issue
I have two PLSQL functions in an Oracle database. Function A uses function B. Therefore to compile function A successfully function B must already be there.
When I use data pump to import the functions it is importing function A before function B, causing a compilation error. I then have to go into SQL Developer and recompile the function before it will work.
My question is, is there any way of making data pump import functions/procedures so that dependecies are loaded in first?
You can not change it unless you load them separately (dependent objects first).
It is likely not worth the hassle - your invalid procedure will be automatocally recompiled on next call. And if it compiles in moment you call it - all is ok.
If you prefer you can try to compile all invalid objects at the end of import (user_objects.status = 'INVALID' ). There is also sql script in oracle server rdbms/admin directory...
I have a script that makes use of a package (PKG_MY_PACKAGE). I will change some of the fields in a query in that package and then recompile it (I don't change or compile any other packages). I run the script and I get an error that looks like
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "USER3.PKG_MY_PACKAGE" has been invalidated
ORA-04065: not executed, altered or dropped package body "USER3.PKG_MY_PACKAGE"
ORA-06508: PL/SQL: could not find program unit being called: "USER3.PKG_MY_PACKAGE"
ORA-06512: at line 34
I run the script again (without changing anything else in the system) and the script executes successfully.
I thought that when I compiled before I executed the script that would fix any invalid references. This is 100% reproducible, and the more I use this script the more annoying it gets. What could cause this, and what would fix it?
(oracle 10g, using PL/SQL Developer 7)
Background
existing state of packages has been discarded means, that your Package had some sort of state.
This is caused by a global variable stored in your Package Body.
Until 11.2.0.2, constants did also cause this behavior (see documentation).
Since the package has already been used in your session, Oracle assumes that this state is relevant for you. Some of these variables might have different values now, and when you recompile the Body, the values are reset.
This exception is thrown, so that your clients know that they can't rely on those variables any more.
Solutions
Remove all global variables and constants (before 11gR2) from the Package Body if possible
Replace global variables by DETERMINISTIC functions (as suggested by this answer)
Defining packages with PRAGMA SERIALLY_REUSABLE causes Oracle to re-initialize the global variables with every call to the server.
Close your session and reconnect before calling the package again.
Reset the state manually (see Paul James' answer)
If you're running stuff in a script try these commands in there prior to running the re-compiled code..
exec DBMS_SESSION.RESET_PACKAGE
exec DBMS_SESSION.MODIFY_PACKAGE_STATE( DBMS_SESSION.REINITIALIZE )
They do what the name might suggest.
Possible issues you can have is:
The package/procedure you are calling is invalid (though it can work if called independently)
check this query whether you have an entry of your package or objects used in your package in this all_objects view
select * from all_objects where status = 'INVALID' and owner = 'SCHEMA_NAME';
Check your package is having global variables? if yes then check if those variable is not being changed by any other session preferable remove those global variables/use function
Run below script to compile all the objects in your schema
begin
dbms_utility.compile_schema('SCHEMA_NAME', false);
end;
Last option if none of the above works then remove all the procedures/function from your package, add new function and try to run your function from the trigger. check if this works then your package is in special lock. After adding a new function/proc it's state will be valid again and then you can add all your actual funcs/procs and remove the newly added function/proc.
The above error : ORA-06508: PL/SQL: could not find program unit being called.
is caused when an attempt was made to call a stored program that could not be found. The program may have been dropped or incompatibly modified, or have compiled with errors.
Check that all referenced programs, including their package bodies, exist and are compatible.
You can run this query to find invalid objects, which may cause the ORA-06508 error:
select
comp_id,
comp_name,
version,
status,
namespace,
schema
from
dba_registry;