unable to execute a store procedure getting error [duplicate] - plsql

This question already has an answer here:
Unable to call an Oracle Function
(1 answer)
Closed 9 years ago.
Can any one help me to execute the below procedure in PL/SQL. I am getting error as
declare
TYPE c_charge_code_arra IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
myarray c_charge_code_arra;
out_val number := 12;
begin
myarray(0) := 'hg';
BRANCH_BKK.air_pkg.airinvoice_pd('01','13070410012','4610032','A','IN','bkkrp_bkk','Asia/Bangkok','56YUSEN',null,myarray,null,'B',out_val);
end;
Error at line 1
ORA-06550: line 7, column 2:
PLS-00306: wrong number or types of arguments in call to 'AIRINVOICE_PD'
ORA-06550: line 7, column 2:
PL/SQL: Statement ignored
Below is the package declaration. When I try to execute the below procedure I get the above error. Thanks in Advance
CREATE OR REPLACE PACKAGE BRANCH_BKK.air_pkg AS
TYPE c_charge_code_arra IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
PROCEDURE airinvoice_pd (in_company IN varchar2,
in_file_no IN varchar2,
c_reference IN varchar2,
in_run_option IN varchar2,
in_invoice_type IN varchar2,
in_user IN varchar2,
c_time_zone in varchar2,
in_payor_code IN varchar2,
in_payor_reference IN varchar2,
i_charge_code IN c_charge_code_arra,
in_invoice_number IN varchar2,
in_invoice_against IN varchar2,
out_message OUT varchar2);

The problem is with your declaration of myarray. You are attempting to re-declare the table type in the calling script, when instead, you need to declare the variable of the table type defined in the package spec:
DECLARE
myarray BRANCH_BKK.air_pkg.c_charge_code_arra;
out_val NUMBER := 12;
BEGIN
myarray (0) := 'hg';
BRANCH_BKK.air_pkg.airinvoice_pd ('01',
'13070410012',
'4610032',
'A',
'IN',
'bkkrp_bkk',
'Asia/Bangkok',
'56YUSEN',
NULL,
myarray,
NULL,
'B',
out_val
);
END;

Related

How to create package in postgresql

CREATE OR REPLACE PACKAGE emp_admin IS FUNCTION get_dept_name ( p_deptno NUMBER DEFAULT 10) RETURN VARCHAR2; FUNCTION update_emp_sal ( p_empno NUMBER, p_raise NUMBER ) RETURN NUMBER; PROCEDURE hire_emp ( p_empno NUMBER, p_ename VARCHAR2, p_job VARCHAR2, p_sal NUMBER, p_hiredate DATE DEFAULT sysdate, p_comm NUMBER DEFAULT 0, p_mgr NUMBER, p_deptno NUMBER DEFAULT 10 ); PROCEDURE fire_emp ( p_empno NUMBER ); END emp_admin;
On executing this on postgres using pgadmin. getting this error
ERROR: syntax error at or near "PACKAGE"
LINE 1: CREATE OR REPLACE PACKAGE emp_admin
^
SQL state: 42601
Character: 19

How to use for loop in sql developer or oracle

This is my code but while I'm running the project, it's showing error like
PLS-00306: wrong number or types of arguments in call to 'TEST_PROCEDURE'
I want to insert multiple records according given date.
CREATE OR REPLACE PROCEDURE TEST_PROCEDURE (
IP_START_DATE IN VARCHAR2,
IP_END_DATE IN VARCHAR2,
IP_MATERIAL_TYPE IN VARCHAR2,
IP_BRM_LIST IN VARCHAR2,
IP_ACTUAL_CONSUMPTION IN VARCHAR2,
IP_YARD_NO IN VARCHAR2,
IP_USER_ID IN VARCHAR2,
IP_USER_IP IN VARCHAR2,
IP_RID IN NUMBER,
IP_OPERATION IN VARCHAR2,
i OUT VARCHAR2,
OUT_RETURN_MSG OUT VARCHAR2,
OUT_RETURN_CODE OUT NUMBER)
IS
BEGIN
OUT_RETURN_MSG := '';
OUT_RETURN_CODE := 0;
BEGIN
IF IP_OPERATION = 'INSERT'
THEN
FOR i IN IP_START_DATE .. IP_END_DATE
LOOP
IF i <= IP_END_DATE
THEN
-- exit loop immediately
INSERT INTO MST_ACTUAL_CONSUMPTION (FROM_DATE,
TO_DATE,
MATERIAL_TYPE,
BRM_TYPE,
ACTUAL_CONSUMPTION,
YARD_NO,
USER_ID,
USER_IP_ADDRESS,
CREATED_DATE)
VALUES (IP_START_DATE,
IP_END_DATE,
IP_MATERIAL_TYPE,
IP_BRM_LIST,
IP_ACTUAL_CONSUMPTION,
IP_YARD_NO,
IP_USER_ID,
IP_USER_IP,
SYSDATE);
EXIT;
END IF;
END LOOP;
END IF;
IF IP_OPERATION = 'UPDATE'
THEN
UPDATE MST_ACTUAL_CONSUMPTION
SET FROM_DATE = IP_START_DATE,
TO_DATE = IP_END_DATE,
MATERIAL_TYPE = IP_MATERIAL_TYPE,
BRM_TYPE = IP_BRM_LIST,
ACTUAL_CONSUMPTION = IP_ACTUAL_CONSUMPTION,
YARD_NO = IP_YARD_NO,
LAST_UPD_TS = SYSDATE,
LAST_UPD_UID = IP_USER_ID
WHERE RID = IP_RID;
-- AND VESSEL_NAME = IP_VESSEL_NAME;
END IF;
OUT_RETURN_CODE := 1;
OUT_RETURN_MSG := 'SUCCESS';
EXCEPTION
WHEN OTHERS
THEN
OUT_RETURN_CODE := 0;
OUT_RETURN_MSG := SQLERRM;
END;
END TEST_PROCEDURE;
You need to select the days between start and end and use that for your loop counter instead of trying to use the variables directly as you currently are. Even though you're passing varchar2 with dates inside them, I still trunc the casted variable for safety to guarantee a whole number.
select trunc(to_date(ip_end_date)) - trunc(to_date(ip_start_date))
into loop_count
from dual;
Change your loop to count by this
if loop_count > 0 then
FOR i IN 1..loop_count loop
and I'm assuming you probably want to change the date for each iteration of the loop to match the day between start and end.
Firstly, you shouldn't be using varchar2 datatype for date datatypes. That is asking for trouble.
Now, since you want to insert records for multiple dates, you can't use for loop iterator for dates the way you do it for numbers as in for i in 1..10.
So, you could use a connect by as a method to generate dates. Use LEVEL pseudocolumn to refer to the current iteration (i in the for loop)
INSERT INTO mst_actual_consumption (
from_date,
TO_DATE, -- don't use this as a column_name as it's a function
material_type,
brm_type,
actual_consumption,
yard_no,
user_id,
user_ip_address,
created_date
)
SELECT
ip_start_date, -- you need to use to_date if you are passing date as strings
ip_end_date,
ip_material_type,
ip_brm_list,
ip_actual_consumption,
ip_yard_no,
ip_user_id,
ip_user_ip,
SYSDATE
FROM
dual
CONNECT BY
level <= ( ip_end_date - ip_start_date ); -- you need to use to_date if you are passing date as strings
I did not understand this part though
IF i <= IP_END_DATE
THEN
-- exit loop immediately
Maybe you were trying this? If so, put it before insert and update
IF ip_end_date <= ip_start_date
THEN
RETURN;
END IF;
EDIT you said:
error has fixed but no records are inserting even one time also
It could be because you are not passing correct dates.As I said in the code comments, you should convert them to dates using to_date function.
For eg: if you are passing the dates as strings in the format dd-mm-yyyy, In the insert, you should use
level <= ( to_date(ip_end_date,'dd-mm-yyyy') - to_date(ip_start_date,'dd-mm-yyyy') )
Same thing has to be done in the select part of insert, if the column in table MST_ACTUAL_CONSUMPTION is of date datatype.
select to_date(ip_start_date,'dd-mm-yyyy'), to_date(ip_end_date,'dd-mm-yyyy')
you can't loop through dates, you can probably do something like this.
create or replace procedure testproc(
startdate in date,
enddate in date
)
as
datediff NUMBER := enddate-startdate;
newdate date := startdate;
begin
FOR i IN 1..datediff LOOP
newdate := newdate+1;
insert into temp values(newdate);
END LOOP;
end;
and for your error it's because you are passing your parameters incorrectly like passing a string where argument requires integer value or you are passing incorrect number of parameters.
create or replace PROCEDURE PROC_ADD_ACTUALCONSUMPTION (
IP_START_DATE IN VARCHAR2,
IP_END_DATE IN VARCHAR2,
IP_MATERIAL_TYPE IN VARCHAR2,
IP_BRM_LIST IN VARCHAR2,
IP_ACTUAL_CONSUMPTION IN VARCHAR2,
IP_YARD_NO IN VARCHAR2,
IP_USER_ID IN VARCHAR2,
IP_USER_IP IN VARCHAR2,
IP_RID IN NUMBER ,
IP_OPERATION IN VARCHAR2,
--S_DATE OUT DATE,
--E_DATE OUT DATE,
--datediff OUT NUMBER,
OUT_RETURN_MSG OUT VARCHAR2,
OUT_RETURN_CODE OUT NUMBER)
IS
BEGIN
OUT_RETURN_MSG := '';
OUT_RETURN_CODE := 0;
-- S_DATE :=TO_DATE(IP_START_DATE,'DD-MM-YYYY HH24:MI:SS');
-- E_DATE :=TO_DATE(IP_END_DATE,'DD-MM-YYYY HH24:MI:SS');
-- datediff :=E_DATE-E_DATE;
BEGIN
IF IP_OPERATION = 'INSERT' THEN
INSERT INTO MST_ACTUAL_CONSUMPTION
(
FROM_DATE,
TO_DATE,
MATERIAL_TYPE,
BRM_TYPE,
ACTUAL_CONSUMPTION,
YARD_NO,
USER_ID,
USER_IP_ADDRESS,
CREATED_DATE
)
select
TO_CHAR((to_date(IP_START_DATE,'DD-MM-YYYY HH24:MI:SS')+ (level-1)),'DD-MM-YYYY') ,
TO_CHAR(to_date(IP_END_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY') ,
IP_MATERIAL_TYPE,
IP_BRM_LIST,
IP_ACTUAL_CONSUMPTION,
IP_YARD_NO,
IP_USER_ID,
IP_USER_IP,
SYSDATE
FROM
dual
CONNECT BY
level <= to_date(IP_END_DATE,'DD-MM-YYYY HH24:MI:SS')-to_date(IP_START_DATE,'DD-MM-YYYY HH24:MI:SS')+1;
-- to_date(IP_START_DATE,'DD-MM-YYYY HH24:MI:SS'):=to_date(IP_START_DATE,'DD-MM-YYYY HH24:MI:SS')+1;
END IF;
END PROC_ADD_ACTUALCONSUMPTION;

using nested table as in Parameter to a Procedure

I have a table T1 and I want to insert multiple rows at a time through a procedure using collection. I have written the code but when I'm trying to execute it throws an error. Please advise.
create table t1 ( id number , name varchar2(10));
/
create or replace PACKAGE PKG1 AS
TYPE TAB_LIST IS TABLE OF T1%ROWTYPE;
PROCEDURE PROC1 (p_val IN TAB_LIST);
END PKG1;
/
create or replace PACKAGE BODY PKG1 AS
PROCEDURE PROC1 (P_VAL IN TAB_LIST
)
IS
BEGIN
FOR i IN p_val.FIRST..p_val.LAST
LOOP
insert INTO T1
(
id, name
)
VALUES
(
p_val(i).id,
p_val(i).name
);
END LOOP;
END;
END;
error after executing
DECLARE
p_val PKG1.TAB_LIST;
BEGIN
p_val := PKG1.TAB_LIST(123,'XYZ');
END;
Error report -
ORA-06550: line 5, column 11:
PLS-00306: wrong number or types of arguments in call to 'TAB_LIST'
ORA-06550: line 5, column 11:
PLS-00306: wrong number or types of arguments in call to 'TAB_LIST'
ORA-06550: line 5, column 2:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
DECLARE
P_VAL PKG1.TAB_LIST := PKG1.TAB_LIST();
BEGIN
P_VAL.extend;
P_VAL(1).id := 123;
P_VAL(1).name := 'XYZ';
PKG1.PROC1( P_VAL );
END;
example for multiple records:
DECLARE
P_VAL PKG1.TAB_LIST := PKG1.TAB_LIST();
BEGIN
for i in 1 .. 10
loop
P_VAL.extend;
P_VAL(P_VAL.LAST).id := i;
P_VAL(P_VAL.LAST).name := 'XYZ' || i;
end loop;
PKG1.PROC1( P_VAL );
END;
#hekko": its not a string .sorry about formatting . The multiple values (n) can be passed from application like this and all should be inserted into table at once.
123 'XYZ'
456 'DFK'
866 'HKK'
#Kaushik :it is not a string but formatting issue.. the question remains the same "I have a table T1 and I want to insert multiple rows at a time through a procedure using collection.

Error when insert into table with a varray column through package procedure

PROBLEM IS HOW TO INSERT INTO VARRAY-
I HAVE A PROCEDURE WHERE I AM DECLARE IN PARAMETER AS TABLE DATATYPE
IN PROCEDURE I USE INSERT STATEMENT TO INSERT INTO TABLE.
I AM FACING PROBLEM TO INSERT INTO VARRAY ALREADY I AM A DECLARING A VARY TYPE IN PACKAGE SPECIFICATION AND USING IN BODY BT ERROR SHOWS:-Error(61,17): PL/SQL: ORA-00932: inconsistent datatypes: expected NUMBER got SCOTT.SYS_PLSQL_75329_19_1
create or replace PACKAGE BODY CBIS_LOAN_PROD_PACKAGE AS
PROCEDURE LOAN_PRODUCT_INSERT_PROCEDURE
(P_PRODUCT_TITLE LOAN_PROD_TAB.PRODUCT_TITLE%TYPE,
P_PRODUCT_SUMMERY LOAN_PROD_TAB.PRODUCT_SUMMERY%TYPE,
P_INTEREST_TYPE LOAN_PROD_TAB.INTEREST_TYPE%TYPE,
P_INTEREST_RATE LOAN_PROD_TAB.INTEREST_RATE%TYPE,
P_SECURITY_REQD LOAN_PROD_TAB.SECURITY_REQD%TYPE,
P_MIN_LOAN_AMT LOAN_PROD_TAB.MIN_LOAN_AMT%TYPE,
P_MAX_LOAN_AMT LOAN_PROD_TAB.PRODUCT_TITLE%TYPE,
P_TERM_MIN LOAN_PROD_TAB.TERM_MIN%TYPE,
P_TERM_MAX LOAN_PROD_TAB.TERM_MAX%TYPE,
P_REPAYMENT_FREQUENCY LOAN_PROD_TAB.REPAYMENT_FREQUENCY%TYPE,
P_REPAYMENT_AMT LOAN_PROD_TAB.REPAYMENT_AMT%TYPE,
P_EARLY_REPAY_ALLOWED LOAN_PROD_TAB.EARLY_REPAY_ALLOWED%TYPE,
P_MIN_AGE_LIMIT LOAN_PROD_TAB.MIN_AGE_LIMIT%TYPE,
P_MAX_AGE_LIMIT LOAN_PROD_TAB.MAX_AGE_LIMIT%TYPE,
V_1 VARCHAR2,
V_2 VARCHAR2,
V_3 VARCHAR2,
V_4 VARCHAR2,
V_5 VARCHAR2,
P_PROD_START_DT LOAN_PROD_TAB.PROD_START_DT%TYPE,
P_PROD_END_DT LOAN_PROD_TAB.PROD_END_DT%TYPE,
P_PROD_STATUS LOAN_PROD_TAB.PROD_STATUS%TYPE)
IS
V_T RESIDENT_VARRAY:=RESIDENT_VARRAY('V_1','V_2','V_3','V_4','V_5');
BEGIN
INSERT INTO LOAN_PROD_TAB
(
PRODUCT_TITLE,
PRODUCT_SUMMERY,
INTEREST_TYPE,
INTEREST_RATE,
SECURITY_REQD,
MIN_LOAN_AMT,
MAX_LOAN_AMT,
TERM_MIN,
TERM_MAX,
REPAYMENT_FREQUENCY,
REPAYMENT_AMT,
EARLY_REPAY_ALLOWED,
MIN_AGE_LIMIT,
MAX_AGE_LIMIT,
RESIDENT,
PROD_START_DT,
PROD_END_DT,
PROD_STATUS)
VALUES(P_PRODUCT_TITLE,
P_PRODUCT_SUMMERY,
P_INTEREST_TYPE,
P_INTEREST_RATE,
P_SECURITY_REQD,
P_MIN_LOAN_AMT,
P_MAX_LOAN_AMT,
P_TERM_MIN,
P_TERM_MAX,
P_REPAYMENT_FREQUENCY,
P_REPAYMENT_AMT,
P_EARLY_REPAY_ALLOWED,
P_MIN_AGE_LIMIT,
P_MAX_AGE_LIMIT,
V_T,/*PROBLEM IS HERE-Error(61,17): PL/SQL: ORA-00932: inconsistent
datatypes: expected NUMBER got SCOTT.SYS_PLSQL_75329_19_1*/
P_PROD_START_DT,
P_PROD_END_DT,
P_PROD_STATUS
);
END LOAN_PRODUCT_INSERT_PROCEDURE;
END;
The error you encounter occurs because a SQL type is not the same as a PL/SQL type.
The type of LOAN_PROD_TAB.RESIDENT column which is of a type you declared at schema level, is not recognized as the same as the type called RESIDENT_VARRAY you declared in the CBIS_LOAN_PROD_PACKAGE package spec.
To make it work, when you declare (and instantiate) the variable V_T, you have to use the same type you used when you declared the LOAN_PROD_TAB.RESIDENT column.
Below is a full example to verify my solution:
CREATE OR REPLACE TYPE mem_type IS VARRAY(5) of VARCHAR2(15);
CREATE TABLE test_va (
va_Name VARCHAR2(10),
va_Address VARCHAR2(20),
va_City VARCHAR2(20),
va_Phone VARCHAR2(8),
va_Members mem_type);
create or replace package test_va_pkg as
TYPE p_mem_type IS VARRAY(5) of VARCHAR2(15); -- cannot be used to insert into test_va.va_Members column!!!!
procedure p_test_va(
p_name VARCHAR2,
p_Address VARCHAR2,
p_City VARCHAR2,
p_Phone VARCHAR2
);
end test_va_pkg;
/
create or replace package body test_va_pkg as
procedure p_test_va(
p_name VARCHAR2,
p_Address VARCHAR2,
p_City VARCHAR2,
p_Phone VARCHAR2
) is
-- v_members_va p_mem_type := p_mem_type('V_1','V_2','V_3','V_4','V_5'); -- doesn't work!
v_members_va mem_type := mem_type('V_1','V_2','V_3','V_4','V_5');
begin
insert into test_va
values (
p_name,
p_Address,
p_City,
p_Phone,
v_members_va
);
commit;
exception
when others then
rollback;
raise;
end p_test_va;
end test_va_pkg;
/
begin
test_va_pkg.p_test_va('Eric Smith', 'N/A', 'London', '12345679');
end;
/
select * from test_va;
Hope it helps!

ORA-06502 error for testing existing values

Here is the procedure and the error the value I am sending the exactly the value which is already existing in the table(have no dependencies).Not sure why the it is throwing the error.
create or replace PROCEDURE TEST (email_address in VARCHAR2,
CatItype in VARCHAR2, opt_status in CHAR,userIns in VARCHAR2,
editstat out VARCHAR2)
AS
eid EMAILDATA.EMAIL_ID%TYPE;
eid1 EMAILDATA.EMAIL_ID%TYPE;
cid EMAILDATA.category_id%TYPE;
cname EMAILDATA.CATEGORY_NAME%TYPE;
pref EMAILDATA.PREFERENCE%TYPE;
Email_val EMAILDATA.EMAIL_ADDRESS%TYPE := email_address;
CatIntType EMAILDATA.INTER_CONTACTTYPE%TYPE := CatItype;
usrins EMAILDATA.USER_INSERTING%TYPE := userIns;
ostat EMAILDATA.PREFERENCE%TYPE := opt_status;
error_flag BOOLEAN ;
Error
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "TEST", line 19
ORA-06512: at line 13
I suppose the problem is here: usrins EMAILDATA.USER_INSERTING%TYPE := userIns;
The max length of VARCHAR2 in SQL (table type) = 4000 characters
The max length in PL/SQL IS 32767
USER_INSERTING is a column in the table EMAILDATA. I suppose it has VARCHAR2 type. In this case the max. number of characters for this variable is limited to 4000 (depending on your DDL).
userIns is a PL/SQL VARCHAR2 variable which can contain up to 32767 characters.

Resources