Why can't execute SCHEMA_NAME.PACKAGE_NAME.PROCEDURE, Oracle - oracle

I have a schema A, Package B and Procedure C. B is in A schema and C is in B's Package Body.
It works fine when I say:
Begin
Exec B.C;
END;
But it throw an error when I say:
Begin
Exec A.B.C;
END;
Error report:
ORA-06550: line 2, column 12:
PLS-00302: component 'B' must be declared
ORA-06550: line 2, column 4:
PL/SQL: Statement ignored
I log in as A so it's in A's schema.
and
SELECT * FROM user_OBJECTS WHERE OBJECT_NAME = 'B';
shows package and package body both valid.

I had the same problem and found the issue. I will write here the answer to close this problem and help other people.
In my case, my user A have execute privilege on a procedure B(just a procedure, not a package, but it's the same). When the user tries to run:
Begin
Exec A.B;
END;
Get the error:
ERROR at line 2:
ORA-06550: line 2, column 7:
PLS-00302: component 'B' must be declared
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored
Problem: That's because a public synonym with name A was created in the database. This is an old database and I am just the DBA, not the developer, but in this case the developer was an uninspired developer. He used 4 types of objects with the same name: user, table, tablespace and public synonym. A public synonym named A in front of a table named A.
Solution: Because you don't know exactly who is using that public synonym I had to found another solution instead of deleting the public synonym. I created a private synonym for that procedure. Now the user can skip the owner of procedure in the execution code and ignore the public synonym. This problem appears in Oracle Database 10.2.0.4.
Begin
Exec B;
END;
PL/SQL procedure successfully completed.
Conclusion: Never use a public/private synonym with the name of the schema.
Hope to help someone. If I didn't made myself clear, please leave a comment.

Fix syntax error in the package, this is a generic PL/SQL compile error message.
Check error points (line 2, column 12) in the PL/SQL where the syntax error occurred, correct it and then try recompiling your code.
Component 'B' must be declared.
After that grant EXECUTE_CATALOG_ROLE to allow user 'A' execute privileges for packages and procedures in the data dictionary.
grant EXECUTE_CATALOG_ROLE to A;

Related

package name is the same as another schema name in ORACLE PL/SQL, how to access another schema object? [duplicate]

Suppose I have schemas A and B.
In schema A I would like to call package X in schema B. However, there exists a package B in schema A.
A:
package B
B:
package X
When I call from schema A:
begin b.x.foo(); end
it looks for procedure X in package B, i.e. A.B.X(), and gets an error.
How can I fully qualify the call to force B to be considered a schema name?
update:
It does seem there's no way to scope the reference to refer to b.x.foo.
CREATE SYNONYM B_X for B.X works. B_X.foo() calls the procedure in schema B.
I don't think you can. From the PL/SQL User's Guide:
"The name resolution rules for PL/SQL and SQL are similar. You can avoid the few differences if you follow the capture avoidance rules. For compatibility, the SQL rules are more permissive than the PL/SQL rules. SQL rules, which are mostly context sensitive, recognize as legal more situations and DML statements than the PL/SQL rules.
PL/SQL uses the same name-resolution rules as SQL when the PL/SQL compiler processes a SQL statement, such as a DML statement. For example, for a name such as HR.JOBS, SQL matches objects in the HR schema first, then packages, types, tables, and views in the current schema.
PL/SQL uses a different order to resolve names in PL/SQL statements such as assignments and procedure calls. In the case of a name HR.JOBS, PL/SQL searches first for packages, types, tables, and views named HR in the current schema, then for objects in the HR schema."
The second bullet above applies. Since the object "B" exists in schema A, that's what the reference resolves to.
I agree with DCookie, this is a normal scoping problem. If you're in this situation though, one way to solve the issue would be to change the CURRENT_SCHEMA:
SQL> exec b.x.foo;
begin b.x.foo; end;
ORA-06550: line 2, column 9:
PLS-00302: component 'X' must be declared
ORA-06550: line 2, column 7:
PL/SQL: Statement ignored
SQL> alter session set current_schema=b;
Session altered
SQL> exec b.x.foo;
PL/SQL procedure successfully completed

Object is invalid PLSQL Procedure

I use a dataset that has billing information:
Table Image
And I want to create a procedure that gives information about a specific bill by giving an invoice id
CREATE OR REPLACE PROCEDURE print_information(
invoiceID varchar(11);
) IS
p_smtable supermarket%ROWTYPE;
BEGIN
SELECT * INTO p_smtable FROM SUPERMARKET
WHERE invoice_id = invoiceID;
DBMS_OUTPUT.PUT_LINE(p_smtable.brancj || p_smtable.city);
END;
The compilation is successful.
Compile
begin
print_information('750-67-8428');
end;
But I get an error that says:
Error starting at line : 12 in command -
begin
print_information('750-67-8428');
end;
Error report -
ORA-06550: line 2, column 1:
PLS-00905: object SYSTEM.PRINT_INFORMATION is invalid
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
The code in the screenshot is different to the version in your question, but both have an error at line 2. The parameter should be varchar2 or supermarket.invoice_id%type, with no semicolon.
Also, we normally use a p_ prefix for parameters, not variables. (There are other conventions, but whatever you use, p_ for a variable is just confusing.)
A fixed version might be:
create or replace procedure print_information
( p_invoice_id supermarket.invoice_id%type )
as
l_market supermarket%rowtype;
begin
select * into l_market
from supermarket
where invoice_id = p_invoice_id;
dbms_output.put_line(l_market.brancj || ' '|| l_market.city);
end;
Whatever tool you are using for development, you need to become familiar with how to display compilation errors.
brancj might be a typo for branch.
I've assumed you want a space between branch and city, otherwise the output would be something like TottenhamLondon rather than Tottenham London.
In Oracle a schema belongs to one user, created with the CREATE USER command. An Oracle Database is the entire thing (all users, all data, storage, memory, processes, everything) so you would not normally create one for something like this.

Why does this db link chain cause a "looping chain of synonyms" error only within an anonymous block?

I am in a position which requires I pull data to my primary database through a daisy chained dblink set up similar to what is described in this answer
DBLINK_SERVER2 -> SYNONYM -> DBLINK_SERVER3
The synonym is set up on server 2 like this:
CREATE OR REPLACE SYNONYM "MY_USER"."THE_VIEW" FOR "THE_VIEW"#"DBLINK_SERVER3"
When I run a simple select statement from server 1, it works fine and pulls back exactly what i'd expect from server 3's view:
SELECT COUNT(*) FROM THE_VIEW#DBLINK_SERVER2;
However, whenever I try to run code in an anonymous block any reference to the dblink will cause a "looping chain of synonyms" error.
DECLARE
testnum VARCHAR2(50);
BEGIN
SELECT COUNT(*) INTO testnum FROM THE_VIEW#DBLINK_SERVER2;
END;
/
Error report -
ORA-06550: line 2, column 22:
PL/SQL: ORA-01775: looping chain of synonyms
ORA-06550: line 2, column 1:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
There aren't any synonyms on server 1 that i can see which reference the view or dblink. If i run this same test on server 2 both the simple command and block work fine when i use the synonym. Any idea why the block fails on server 1 but not if i run the same thing outside of the block? Is this some kind of permissions problem?
*** Edit ***
We never determined what was causing this, but the DBA changed it so that we were referencing a view in server 2 instead of a symlink. That resolved our problem.
CREATE VIEW THE_VIEW AS SELECT * FROM THE_VEW#DBLINK_SERVER3

Oracle: error using DMBS_IJOBS

I've got the following error using the following code:
BEGIN
sys.dbms_ijob.run(25950);
COMMIT;
EXCEPTION
WHEN others
THEN
DBMS_OUTPUT.put_line (SQLERRM);
RAISE;
END;
ORA-06550: line 2, column 5:
PLS-00201: identifier 'SYS.DBMS_IJOB' must be declared
ORA-06550: line 2, column 5:
PL/SQL: Statement ignored
I guess you're not running this as SYS. Either you need to run it as SYS or you need a DBA to grant you execute privileges on the package.
While #APC is correc that this is a permissions issue, I would strongly question why you are using the DBMS_IJOB package in the first place. It is an undocumented, internal package, not something that should generally be used by developers. And there is a perfectly good RUN procedure in the public, documented DBMS_JOB package that you can use instead
BEGIN
dbms_job.run( 25950 );
commit;
END;
/
There is no reason to use the internal, undocumented package when the public, documented package has a method to do what you want.
I don't think there is a package called DBMS_IJOB in Oracle Database. It should be DBMS_JOB.

Including the schema name when calling a PL/SQL procedure doesn't work in one schema but does in another

This problem came up when trying out the Unit Testing capabilities of SQLDeveloper.
When running a test for a procedure that is created within my schema I am seeing an error however when the same procedure is run in one of the oracle supplied schemas it works without an issue.
SQL Developer generates the following calls:
1) This one doesn't work (error is shown below):
BEGIN
"IANC"."SIMPLE_PARAMETER"(P_X => 123);
END;
2) This one does:
BEGIN
"HR"."SIMPLE_PARAMETER"(P_X => 123);
END;
This is the procedure:
CREATE OR REPLACE PROCEDURE SIMPLE_PARAMETER
(
P_X IN NUMBER
)
IS
BEGIN
null;
END SIMPLE_PARAMETER;
The following is the output from SQLPLUS, where you can see when the procedure is run in my schema I see an error whilst when running the same procedure in another schema the procedure works as expected:
In case of need my I am using Oracle Enterprise Edition 11.2.0.1.0
Update
Screen shot showing procedure signatures
I should also mention that if I remove the schema name from the procedure call then the procedure runs and completes as expected.
Thanks in advance for any help received.
Are you sure that the SIMPLE_PARAMETER procedure in IANC is the same (or at least has the same signature) as the one in HR? What do you get from `DESCRIBE "IANC"."SIMPLE_PARAMETER".
(P.S. since your identifiers are all upper-case, you shouldn't need the double quotes at all.)
Added: Another possibility is that you have a package called IANC in the IANC schema, so Oracle is looking for a procedure in that package called SIMPLE_PARAMETER that does not exist. Example:
SQL> exec bigdecimaltest
PL/SQL procedure successfully completed.
SQL> exec dcosta.bigdecimaltest
PL/SQL procedure successfully completed.
SQL> create or replace package dcosta as
2 end;
3 /
Package created.
SQL> exec dcosta.bigdecimaltest
BEGIN dcosta.bigdecimaltest; END;
*
ERROR at line 1:
ORA-06550: line 1, column 14:
PLS-00302: component 'BIGDECIMALTEST' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
This seems like buggy behavior -- if the attempt to resolve the name as package.member doesn't succeed, I think Oracle ought to then try it as schema.object, but it looks like once it has found a match on the package name it won't reconsider that.

Resources