I created a synonym for a package, but I can't do anything with it, including a simple desc command. Check out the codes:
Create package sql (executed on owner user)
create or replace PACKAGE pkg_elmah$log_error
IS
PROCEDURE LogError
(
v_ErrorId IN elmah$error.errorid%TYPE,
v_Application IN elmah$error.application%TYPE,
v_Host IN elmah$error.host%TYPE,
v_Type IN elmah$error.type%TYPE,
v_Source IN elmah$error.source%TYPE,
v_Message IN elmah$error.message%TYPE,
v_User IN elmah$error.username%TYPE,
v_AllXml IN elmah$error.allxml%TYPE,
v_StatusCode IN elmah$error.statuscode%TYPE,
v_TimeUtc IN elmah$error.timeutc%TYPE
);
END pkg_elmah$log_error;
Create synonym and test sql (executed on not owner user)
CREATE SYNONYM pkg_elmah$log_error FOR DRSP.pkg_elmah$log_error;
desc pkg_elmah$log_error;
---------RESULT: object does not exist
execute pkg_elmah$log_error.logerror;
---------RESULT: identifier pkg_elmah$log_error must be declared
These codes run fine when I log in with the owner of these objects.
Grant was given as follows (I seem unable to give to the procedure only, as it gives an ORA-04042, so I gave it to the package):
grant execute on PKG_ELMAH$LOG_ERROR to not_owner
Environment: WINDOWS 7 64bits; SQL DEVELOPER 4.0.3.16; ORACLE CLIENT 11.2
Details of the synonym:
Details of the package:
You are doing something in the wrong order or have otherwise omitted to tell us something. Because the instructions carried out in the right order work as expected:
SQL> conn a/a
Connected.
USER is "A"
SQL> create or replace PACKAGE pkg_elmah$log_error
2 IS
3 PROCEDURE LogError
4 (
5 v_ErrorId IN number,
6 v_Application IN varchar2,
7 v_Host IN varchar2,
8 v_Type IN varchar2,
9 v_Source IN varchar2,
10 v_Message IN varchar2,
11 v_User IN varchar2,
12 v_AllXml IN varchar2,
13 v_StatusCode IN varchar2,
14 v_TimeUtc IN date
15 );
16
17 END pkg_elmah$log_error;
18 /
Package created.
SQL> grant execute on PKG_ELMAH$LOG_ERROR to b
2 /
Grant succeeded.
SQL> conn b/b
Connected.
USER is "B"
SQL> CREATE SYNONYM pkg_elmah$log_error FOR A.pkg_elmah$log_error;
Synonym created.
SQL> desc pkg_elmah$log_error
PROCEDURE LOGERROR
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
V_ERRORID NUMBER IN
V_APPLICATION VARCHAR2 IN
V_HOST VARCHAR2 IN
V_TYPE VARCHAR2 IN
V_SOURCE VARCHAR2 IN
V_MESSAGE VARCHAR2 IN
V_USER VARCHAR2 IN
V_ALLXML VARCHAR2 IN
V_STATUSCODE VARCHAR2 IN
V_TIMEUTC DATE IN
SQL> exec pkg_elmah$log_error.logerror
BEGIN pkg_elmah$log_error.logerror; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'LOGERROR'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL>
Related
Here is one of oracle procedure. There is a cursor called r_ba.
DECLARE
r_ba SYS_REFCURSOR;
BEGIN
OPEN r_ba FOR
SELECT head.*,
line.jenis_pekerjaan,
line.deskripsi_pekerjaan,
line.akun,
line.rate_ppn,
line.dpp,
line.ppn,
line.total_realisasi,
line.major,
line.minor,
line.sla
FROM idm_ap_mtc_acl_header_tmp head, idm_ap_mtc_acl_lines_tmp line
WHERE head.no_ba = line.no_ba AND head.req_id = line.req_id AND head.req_id = n_req_id;
create_invoice_ap2 (
p_org_id => p_org_id,
p_user_id => p_user_id,
p_branch_code => v_branch_code,
r_ba => r_ba);
END;
and how call that cursor in this procedure ?
PROCEDURE create_invoice_ap2 (p_org_id IN NUMBER,
p_user_id IN NUMBER,
p_branch_code IN VARCHAR2,
r_ba IN SYS_REFCURSOR)
IS
r_tax_info rt_tax_info;
rt_ba SYS_REFCURSOR;
BEGIN
------------ setup ------------
r_tax_info := get_tax_code (
p_date => rt_ba.tgl_ba,
p_group_tax_name => rt_ba.tax_name,
p_ppn_rate => rt_ba.ppn_rate,
p_dc_code => rt_ba.dc_code);
END;
oracle give me error
[Error] PLS-00487 (707: 64): PLS-00487: Invalid reference to variable 'RT_BA'
Anyone could suggest me a way to accomplish this?
Thanks
If you're passing refcursor into a parameter named r_ba, then - I believe - you should use it, not declare another (rt_ba):
PROCEDURE create_invoice_ap2 (p_org_id IN NUMBER,
p_user_id IN NUMBER,
p_branch_code IN VARCHAR2,
r_ba IN SYS_REFCURSOR)
IS
r_tax_info rt_tax_info;
-- rt_ba SYS_REFCURSOR; --> you don't need it
BEGIN
------------ setup ------------
r_tax_info := get_tax_code (
p_date => r_ba.tgl_ba,
p_group_tax_name => r_ba.tax_name,
p_ppn_rate => r_ba.ppn_rate,
p_dc_code => r_ba.dc_code);
END; ----
^
|
r_ba, not rt_ba
Also, note that you should generally avoid select * because it can lead to ambiguity if there are columns with the same name as columns in other tables, so Oracle doesn't know which one you want to use.
The same goes for typos; for example, in anonymous PL/SQL block you're selecting line.rate_ppn, while procedure uses p_ppn_rate => r_ba.ppn_rate (rate_ppn vs. ppn_rate). Maybe it is OK because there's ppn_rate column in head table (which is in select head.*) but - once again - that's difficult to debug.
Furthermore, you can't use refcursor that way - you have to fetch from it. Have a look at example based on Scott's sample schema. Here's a procedure that accepts refcursor as a parameter and does something with it:
SQL> create or replace procedure p_test (r_ba in sys_refcursor)
2 is
3 l_dname varchar2(20);
4 begin
5 l_dname := r_ba.dname;
6 end;
7 /
Warning: Procedure created with compilation errors.
SQL> show err
Errors for PROCEDURE P_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/3 PL/SQL: Statement ignored
5/19 PLS-00487: Invalid reference to variable 'R_BA'
SQL>
See? The same error you got. Therefore, fetch:
SQL> create or replace procedure p_test (r_ba in sys_refcursor)
2 is
3 l_row dept%rowtype;
4 begin
5 loop
6 fetch r_ba into l_row;
7 exit when r_ba%notfound;
8 dbms_output.put_line(l_row.deptno ||', '|| l_row.dname ||', '|| l_row.loc);
9 end loop;
10 end;
11 /
Procedure created.
SQL> declare
2 r_ba sys_refcursor;
3 begin
4 open r_ba for select deptno, dname, loc from dept;
5 p_test (r_ba);
6 end;
7 /
10, ACCOUNTING, NEW YORK
20, RESEARCH, DALLAS
30, SALES, CHICAGO
40, OPERATIONS, BOSTON
PL/SQL procedure successfully completed.
SQL>
Now it is OK.
I don't know what you're doing with r_tax_info, how many rows refcursor contains (whether you need to use a loop or not), but - that's the general idea. Fetch first, use it next.
So, in this code what exactly PROMPT syntax do?
PROMPT create or replace procedure abc (p_name, p_id)
AUTHID CURRENT_USER
as
begin
dbms_output.put_line('hi');
end;
PROMPT has a meaning if you run some code in SQL*Plus (not many people do that nowadays). It displays text what follows that keyword.
SQL> help prompt
PROMPT
------
Sends the specified message or a blank line to the user's screen.
PRO[MPT] [text]
SQL> prompt hello there!
hello there!
SQL>
In your case, it produces unwanted result as it displays the create procedure (instead of creating it):
SQL> PROMPT create or replace procedure abc (p_name, p_id)
create or replace procedure abc (p_name, p_id)
SQL> AUTHID CURRENT_USER
SP2-0734: unknown command beginning "AUTHID CUR..." - rest of line ignored.
SQL> as
SP2-0042: unknown command "as" - rest of line ignored.
SQL> begin
2 dbms_output.put_line('hi');
3 end;
4 /
hi
PL/SQL procedure successfully completed.
SQL>
You got the result, but just as pure accident as
begin
dbms_output.put_line('hi');
end;
was a valid PL/SQL block.
Code you posted (without prompt) is invalid:
SQL> create or replace procedure abc (p_name, p_id)
2 AUTHID CURRENT_USER
3 as
4 begin
5 dbms_output.put_line('hi');
6 end;
7 /
Warning: Procedure created with compilation errors.
SQL> show err
Errors for PROCEDURE ABC:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/22 PLS-00103: Encountered the symbol "," when expecting one of the
following:
in out <an identifier> <a double-quoted delimited-identifier>
... long double ref char time timestamp interval date binary
national character nchar
3/1 PLS-00103: Encountered the symbol "AS" when expecting one of the
following:
with authid cluster order deterministic parallel_enable
pipelined result_cache
6/4 PLS-00103: Encountered the symbol "end-of-file" when expecting
one of the following:
end not pragma final instantiable order overriding static
member constructor map
SQL>
What does it mean? Procedure's parameters have to have datatype:
SQL> create or replace procedure abc (p_name in varchar2, p_id in number)
2 AUTHID CURRENT_USER
3 as
4 begin
5 dbms_output.put_line('hi');
6 end;
7 /
Procedure created.
SQL> exec abc(null, null);
hi
PL/SQL procedure successfully completed.
SQL>
Error message
CREATE TABLE DEPARTMENT(DID INT,DNAME VARCHAR2(20),DLOC VARCHAR2(20));
INSERT INTO DEPARTMENT VALUES(101,'SRINATH','HINDUPUR');
INSERT INTO DEPARTMENT VALUES(102,'SAINATH','ANANTAPUR');
create or replace PROCEDURE ADD_DEPARTMENT
(P_DID IN DEPARTMENT.DID%TYPE,
P_DNAME IN DEPARTMENT.DNAME%TYPE,
P_DLOC IN DEPARTMENT.DLOC%TYPE,
P_ERROR_MSG OUT VARCHAR2)
IS
BEGIN
INSERT INTO DEPARTMENT(DID,DNAME,DLOC)VALUES(P_DID,P_DNAME,P_DLOC);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
P_ERROR_MSG:=SQLERRM;
END ADD_DEPARTMENT;
iam writing a simple procedure try to excute but it shows object_id:invalid identifier how i can solve
complete procedure execution image
One of your column names may be wrong in the parameter list/insert. Try just using varchar2 for all of them and see if that helps
create or replace PROCEDURE ADD_DEPT2
(P_DEPTNO IN VARCHAR2,
P_DNAME IN VARCHAR2,
P_LOC IN VARCHAR2,
P_ERROR_MSG OUT VARCHAR2)
IS
BEGIN
INSERT INTO DEPT1(DEPTNO,DNAME,LOC)VALUES(P_DEPTNO,P_DNAME,P_LOC);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
P_ERROR_MSG :=SQLERRM;
END ADD_DEPT2;
"it will come same error can be displayed"
No, no it won't. Let's prove it by running the code you posted.
Here is your table:
SQL> CREATE TABLE DEPARTMENT(DID INT,DNAME VARCHAR2(20),DLOC VARCHAR2(20));
Table created.
SQL> INSERT INTO DEPARTMENT VALUES(101,'SRINATH','HINDUPUR');
1 row created.
SQL> INSERT INTO DEPARTMENT VALUES(102,'SAINATH','ANANTAPUR');
1 row created.
SQL>
Here is your procedure:
SQL> create or replace PROCEDURE ADD_DEPARTMENT
2 (P_DID IN DEPARTMENT.DID%TYPE,
3 P_DNAME IN DEPARTMENT.DNAME%TYPE,
4 P_DLOC IN DEPARTMENT.DLOC%TYPE,
5 P_ERROR_MSG OUT VARCHAR2)
6 IS
7 BEGIN
8 INSERT INTO DEPARTMENT(DID,DNAME,DLOC)VALUES(P_DID,P_DNAME,P_DLOC);
9 COMMIT;
10 EXCEPTION
11 WHEN OTHERS THEN
12 P_ERROR_MSG:=SQLERRM;
13 END ADD_DEPARTMENT;
14 /
Procedure created.
SQL>
And lo! not only does it compile but it runs without error too.
SQL> set serveroutput on
SQL> declare
2 v varchar2(128);
3 begin
4 add_department(666, 'Area 51', 'Roswell', v);
5 end;
6 /
PL/SQL procedure successfully completed.
SQL> select * from department;
DID DNAME DLOC
---------- -------------------- --------------------
101 SRINATH HINDUPUR
102 SAINATH ANANTAPUR
666 Area 51 Roswell
SQL>
So once again I ask, what is the problem?
"PLS-00905: object SCOTT.ADD_DEPARTMENT is invalid"
In SQL*Plus:
Connect as SCOTT
alter procedure add_department compile;
show errors
Or apply the equivalent sequence for whatever IDE you use to write your code.
I have the below pl/sql procedure
PROCEDURE insert_p(
p_batch_rec IN ra_batches%rowtype,
p_batch_id OUT NOCOPY ra_batches.batch_id%type,
p_name OUT NOCOPY ra_batches.name%type
)
batch_id is NUMBER(18,0) and p_name is VARCHAR2(50 CHAR)
I'm calling the procedure with
insert_p (l_batch_rec, p_batch_id, p_name);
where p_batch_id:=NULL and p_name:=NULL
I get the conversion error only on the first time I run the procedure. If I run again without changes, it runs fine. To reproduce the error, I disconnect and connect again.
Any ideas why does this error come and how should I resolve the same???
Does the error happen in the initialization part of a package that is used by the function?
You should be able to easily find exactly where the error happens. By default, Oracle will display the object and the line number of the error. (Although, to my great frustration, I find that it is very common for people to write when others then [poor logging that throws out line number].)
SQL> --Create package
SQL> create or replace package test_package is
2 procedure test_procedure;
3 conversion_error number;
4 end;
5 /
Package created.
SQL> --Create package body. Note the initialization part that will fail.
SQL> create or replace package body test_package is
2 procedure test_procedure is
3 begin
4 null;
5 end;
6 begin
7 conversion_error := 'This is not a number';
8 end;
9 /
Package body created.
SQL> --This will fail the first time
SQL> begin
2 test_package.test_procedure;
3 end;
4 /
begin
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "JHELLER.TEST_PACKAGE", line 7
ORA-06512: at line 2
SQL> --But will now work until you reconnect, or run DBMS_SESSION.RESET_PACKAGE.
SQL> begin
2 test_package.test_procedure;
3 end;
4 /
PL/SQL procedure successfully completed.
SQL>
I'm attempting to create a procedure in Oracle Express Server (Application Express 2.1.0.00.39) using the web interface.
This is the SQL I'm running via the SQL Commands option in the web interface
CREATE OR REPLACE PROCEDURE my_procedure (listOfNumbers num_list,
v_value varchar2)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
UPDATE my_table
SET my_column = v_value
WHERE my_row_id IN (SELECT column_value
FROM TABLE(listOfNumbers));
COMMIT;
END;
UPDATE:
Changed SELECT column_value FROM TABLE to SELECT column_value FROM TABLE(listOfNumbers) but now I get the following error:
PLS-00201: identifier 'num_list' must
be declared
UPDATE 2:
Here is how I created my type:
CREATE OR REPLACE TYPE "num_list" as table of NUMBER(38,1)
/
Seems the error is being caused on the parameter declaration line:
(listOfNumbers num_list, v_value varchar2)
Below is the object details as displayed by the Oracle Database Express Edition web interface.
Try ...TABLE(CAST(listOfNumbers AS num_list)).
The SQL parser simply sees a bind placeholder in place of listOfNumbers, and since it's a custom type you need to tell it what type it is.
This will only work if num_list has been defined as a type in the schema, not just declared as a type in a PL/SQL block.
Your code works - providing the array type has been declared correctly (see below). As you are still having a problem I suspect that is where you are going wrong. But you need to post the code you are using to create the NUM_LIST type in order for us to correct it.
My test data:
SQL> select * from my_table
2 /
MY_COLUMN MY_ROW_ID
-------------------- ----------
APC 1
XYZ 2
JFK 3
SQL>
In order to use a type in a SQL statement we must create it as a SQL object:
SQL> create type num_list as table of number;
2 /
Type created.
SQL>
SQL>
SQL> create or replace procedure my_procedure
2 (listofnumbers num_list,
3 v_value varchar2)
4 is
5 begin
6
7 update my_table
8 set my_column = v_value
9 where my_row_id in (select column_value
10 from table(listofnumbers));
11
12 end;
13 /
Procedure created.
SQL>
Executing the procedure:
SQL> declare
2 n num_list := num_list(1,3);
3 begin
4 my_procedure (n , 'FOX IN SOCKS');
5 end;
6 /
PL/SQL procedure successfully completed.
SQL>
And lo!
SQL> select * from my_table
2 /
MY_COLUMN MY_ROW_ID
-------------------- ----------
FOX IN SOCKS 1
XYZ 2
FOX IN SOCKS 3
SQL>
Apparently I was creating the type with quotes around the name:
The following didn't work:
CREATE OR REPLACE TYPE "NUMBER_T" as table of NUMBER(38,1)
When I did it without the quotes and then created the procedure, it was able to recognize it.
The following did work:
CREATE OR REPLACE TYPE NUMBER_T as table of NUMBER(38,1)
I'm not sure why, but it worked.