When I am executing the package I get an error message:
error in the emp_test ORA-06530: Reference to uninitialized composite
Can u explain how I can initialized an object type in a package?
CREATE OR REPLACE TYPE emp_obj AS OBJECT
(
emp_no number,
salary number,
job varchar2(20)
);
CREATE OR REPLACE PACKAGE BODY emp_dummy_pk IS
PROCEDURE emp_test IS
CURSOR emp_cur IS
SELECT empno, sal, job FROM emp;
l_emp_no emp_obj;
BEGIN
FOR emp_rec IN emp_cur LOOP
l_emp_no.emp_no := emp_rec.empno;
l_emp_no.salary := emp_rec.sal;
l_emp_no.job := emp_rec.job;
BEGIN
emp_pk.emp_chk( p_emp_no => l_emp_no );
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line( 'error in the emp_pk.emp_no ' || SQLERRM );
END;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line( 'error in the emp_test ' || SQLERRM );
END;
END;
BEGIN
emp_dummy_pk.emp_test;
END;
You can initialize it using the constructor:
l_emp_no := NEW emp_obj( emp_rec.empno, emp_rec.sal, emp_rec.job );
Related
Just started with the issue of procedures in PL/SQL Oracle and I am presenting a problem at the time of executing it, it indicates the error ORA-00984
The following is the code of the procedure I am performing
create or replace PROCEDURE P_FILEUPLOAD_XML IS
BEGIN
INSERT INTO SPRCMNT (
SPRCMNT_CMTT_CODE,
SPRCMNT_TEXT,
SPRCMNT_TEXT_NAR)
VALUES(P_CMTT_CODE,
P_TEXT,
P_TEXT_NAR);
EXCEPTION WHEN OTHERS THEN
COMMIT;
END;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error:' || SQLERRM);
DBMS_LOB.CLOSE(l_loc);
--dbms_output.put_line('P_RET_VAL:' || P_RET_VAL);
END;
This is the error when saving my procedure
PL/SQL: ORA-00984: column not allowed here
I do not know if I am missing any declaration of variables or something, as I say I am just beginning with the issue of procedures and request your help.
You can use this method to insert into your table. Where you assign the variables inside the procedure
create or replace PROCEDURE P_FILEUPLOAD_XML AS
-- Declare the Variables
P_CMTT_CODE VARCHAR2(200);
P_TEXT VARCHAR2(200);
P_TEXT_NAR VARCHAR2(200);
BEGIN
-- Set variables with a value
P_CMTT_CODE := 'VALUE 1';
P_TEXT := 'VALUE 2';
P_TEXT_NAR := 'VALUE 3';
-- Insert into table
INSERT INTO SPRCMNT
( SPRCMNT_CMTT_CODE,
SPRCMNT_TEXT,
SPRCMNT_TEXT_NAR )
VALUES
( P_CMTT_CODE,
P_TEXT,
P_TEXT_NAR );
EXCEPTION
-- Catch error and log result
WHEN OTHERS THEN
dbms_output.put_line('Error:' || SQLERRM);
END;
Or alternative pass the variables into the procedure. both will achieve the same result
create or replace PROCEDURE P_FILEUPLOAD_XML(P_CMTT_CODE VARCHAR2,P_TEXT VARCHAR2, P_TEXT_NAR VARCHAR2) AS
BEGIN
-- Insert into table
INSERT INTO SPRCMNT
( SPRCMNT_CMTT_CODE,
SPRCMNT_TEXT,
SPRCMNT_TEXT_NAR )
VALUES
( P_CMTT_CODE,
P_TEXT,
P_TEXT_NAR );
EXCEPTION
-- Catch error and log result
WHEN OTHERS THEN
dbms_output.put_line('Error:' || SQLERRM);
END;
-- How to run procedure
BEGIN
P_FILEUPLOAD_XML('VALUE1' , 'VALUE2', 'VALUE3');
END;
Use exception in a procedure.
Procedure for insert into statement.
CREATE OR REPLACE PROCEDURE pSaveProductGroup (p_parentCode VARCHAR2, p_nameGroup VARCHAR2) IS
v_var "ProductGroups"."code"%type;
BEGIN
select p."code" into v_var
from "ProductGroups" p
where p."code"=p_parentCode;
if v_var is not null then
INSERT INTO "ProductGroups"
("parentCode","nameGroup")
VALUES(p_parentCode,p_nameGroup);
end if;
EXCEPTION
WHEN v_var is null then
dbms_output.put_line('Undefined group.');
END;
It should print exception when needed.
Error: Error(18,12): PLS-00103: Encountered the symbol "IS" when expecting one of the following: . then or
You can do something like this to catch the exception.
CREATE OR REPLACE PROCEDURE pSaveProductGroup (p_parentCode VARCHAR2,
p_nameGroup VARCHAR2)
IS
v_var "ProductGroups"."code"%TYPE;
myex EXCEPTION;
PRAGMA EXCEPTION_INIT (myex, -20016);
BEGIN
SELECT p."code"
INTO v_var
FROM "ProductGroups" p
WHERE p."code" = p_parentCode;
IF v_var IS NOT NULL
THEN
INSERT INTO "ProductGroups" ("parentCode", "nameGroup")
VALUES (p_parentCode, p_nameGroup);
ELSE
IF (v_var IS NULL)
THEN
RAISE myex;
END IF;
END IF;
EXCEPTION
WHEN myex
THEN
DBMS_OUTPUT.put_line (
'ERROR_STACK: "Undefined group --> ' || DBMS_UTILITY.format_error_stack);
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line (
'ERROR_STACK: NO_DATA_FOUND --> ' || DBMS_UTILITY.format_error_stack);
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'ERROR_STACK: OTHERS --> ' || DBMS_UTILITY.format_error_stack);
END;
The modified version of the procedure
CREATE OR REPLACE PROCEDURE pSaveProductGroup (p_parentCode VARCHAR2,
p_nameGroup VARCHAR2)
IS
v_var "ProductGroups"."code"%TYPE;
myex EXCEPTION;
PRAGMA EXCEPTION_INIT (myex, -20016);
BEGIN
SELECT p."code"
INTO v_var
FROM "ProductGroups" p
WHERE p."code" = p_parentCode;
IF v_var IS NOT NULL
THEN
INSERT INTO "ProductGroups" ("parentCode", "nameGroup")
VALUES (p_parentCode, p_nameGroup);
ELSE
RAISE myex;
END IF;
EXCEPTION
WHEN myex
THEN
DBMS_OUTPUT.put_line (
'ERROR_STACK: Undefined group --> ' || DBMS_UTILITY.format_error_stack);
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line (
'ERROR_STACK: NO_DATA_FOUND --> ' || DBMS_UTILITY.format_error_stack);
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'ERROR_STACK: OTHERS --> ' || DBMS_UTILITY.format_error_stack);
END;
I am using Oracle 12, and I want to make a dynamic procedure which selects rows from specific table but according to an unknown conditio. That condition will be specified as input parameter.
Suppose I have a column called employee id and I want to call the procedure
with the following condition
execute s('employeeid = 2')
My code is
create or replace procedure s (condition varchar)
as
TYPE EmpCurTyp IS REF CURSOR; -- define weak REF CURSOR type
emp_cv EmpCurTyp; -- declare cursor variable
my_ename VARCHAR2(15);
my_sal NUMBER := 2;
mycondition varchar2(100):=condition;
BEGIN
OPEN emp_cv FOR -- open cursor variable
'SELECT employeeid, employeename FROM employees WHERE = :s' USING mycondition;
END;
but I am getting an error
missing expression
What am I doing wrong, and will the result of this procedure be selected rows from employees table that satisfy applied condition ?
The USING is meant to handle values, not pieces of code; if you need to edit your query depending on an input parameter ( and I believe this is a very dangerous way of coding), you should treat the condition as a string to concatenate to the query.
For example, say you have this table:
create table someTable(column1 number)
This procedure does somthing similar to what you need:
create or replace procedure testDyn( condition IN varchar2) is
cur sys_refcursor;
begin
open cur for 'select column1 from sometable where ' || condition;
/* your code */
end;
Hot it works:
SQL> exec testDyn('column1 is null');
PL/SQL procedure successfully completed.
SQL> exec testDyn('column99 is null');
BEGIN testDyn('column99 is null'); END;
*
ERROR at line 1:
ORA-00904: "COLUMN99": invalid identifier
ORA-06512: at "ALEK.TESTDYN", line 4
ORA-06512: at line 1
This is not embedded in a procedure yet but I tested this and works:
DECLARE
TYPE OUT_TYPE IS TABLE OF VARCHAR2 (20)
INDEX BY BINARY_INTEGER;
l_cursor INTEGER;
l_fetched_rows INTEGER;
l_sql_string VARCHAR2 (250);
l_where_clause VARCHAR2 (100);
l_employeeid VARCHAR2 (20);
l_employeename VARCHAR2 (20);
l_result INTEGER;
o_employeeid OUT_TYPE;
o_employeename OUT_TYPE;
BEGIN
l_cursor := DBMS_SQL.OPEN_CURSOR;
l_sql_string := 'SELECT employeeid, employeename FROM employees WHERE ';
l_where_clause := 'employeeid = 2';
l_sql_string := l_sql_string || l_where_clause;
DBMS_SQL.PARSE (l_cursor, l_sql_string, DBMS_SQL.V7);
DBMS_SQL.DEFINE_COLUMN (l_cursor,
1,
l_employeeid,
20);
DBMS_SQL.DEFINE_COLUMN (l_cursor,
2,
l_employeename,
20);
l_fetched_rows := 0;
l_result := DBMS_SQL.EXECUTE_AND_FETCH (l_cursor);
LOOP
EXIT WHEN l_result = 0;
DBMS_SQL.COLUMN_VALUE (l_cursor, 1, l_employeeid);
DBMS_SQL.COLUMN_VALUE (l_cursor, 2, l_employeename);
l_fetched_rows := l_fetched_rows + 1;
o_employeeid (l_fetched_rows) := l_employeeid;
o_employeename (l_fetched_rows) := l_employeename;
l_result := DBMS_SQL.FETCH_ROWS (l_cursor);
END LOOP;
DBMS_SQL.CLOSE_CURSOR (l_cursor);
DBMS_OUTPUT.PUT_LINE (o_employeeid (1));
DBMS_OUTPUT.PUT_LINE (o_employeename (1));
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE ('GENERAL FAILURE: ' || SQLERRM);
END;
Bellow is my procedure.
create or replace procedure my_log (action in varchar2, message in varchar2 )
is
begin
Insert into my_log_table (ACTION, MESSAGE, EVENT_DATE)
values (action, message, sysdate);
commit;
end;
/
CREATE OR REPLACE PROCEDURE "CUSTOMER_INCREMENTAL" ()
IS
err_num NUMBER;
err_msg VARCHAR2(4000);
BEGIN
my_log ('Start','My message');
INSERT INTO NDB_AML_CUSTOMER
(ID, TITLE,...)
SELECT ID, TITLE,...
FROM NDB_CUSTOMER_NEW
WHERE DATE_TIME > (SELECT RUN_DATE FROM CHECK_POINT WHERE TABLE_NAME = 'NDB_CUSTOMER_NEW');
UPDATE CHECK_POINT SET RUN_DATE = SYSDATE WHERE TABLE_NAME = 'NDB_CUSTOMER_NEW';
COMMIT;
my_log ('End','My message');
EXCEPTION
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SQLERRM;
my_log ('Error' , errnum ||' - ' || err_msg);
END;
/
When I compile it gives the error PLS-00103: Encountered the symbol ")" when expecting one of the following: current delete exists prior. Any suggestions?
You do not need () if function or procedure has no parameters.
I have a package specification:
G_PKG_NAME CONSTANT VARCHAR2(30) := 'XX_CUST_PKG';
PROCEDURE customer_load
( errbuff OUT NOCOPY VARCHAR2
, retcode OUT NOCOPY VARCHAR2);
And body with procedure which calls to HZ_PARTY_V2PUB API. It uses cursor to take data from a table and then sends it to API :
PROCEDURE create_customer
( errbuff OUT NOCOPY VARCHAR2
, retcode OUT NOCOPY VARCHAR2)
IS
ERR_SOURCE CONSTANT VARCHAR2(100) := G_PKG_NAME ||'.create_customer';
CURSOR c_load
IS
SELECT rowid row_id
, person_first_name
, person_last_name
, title
, known_as
, person_identifier
, gender
FROM xx_customer_info
WHERE NVL(status_flag, 'X') <> 'S';
r_load c_load%ROWTYPE;
--p_init_msg_list VARCHAR2(1) := FND_API.G_TRUE;
v_gender VARCHAR2(30); --hz_parties.sex%TYPE;
v_title VARCHAR2(60); --hz_parties.title%TYPE;
--API record type
person_rec HZ_PARTY_V2PUB.PERSON_REC_TYPE;
-- API output variables
x_return_status VARCHAR2(1);
x_msg_count NUMBER;
x_msg_data VARCHAR2(2000);
x_party_id NUMBER;
x_party_number VARCHAR2(30);
x_profile_id NUMBER;
EXC_VALDN_ERR EXCEPTION;
BEGIN
errbuff := ' ';
retcode := RTN_SUCCESS;
msg_log ('Inside '||ERR_SOURCE);
FOR r_load in c_load LOOP
BEGIN
x_msg_data := NULL;
x_return_status := fnd_api.G_RET_STS_SUCCESS;
fnd_msg_pub.initialize;
-- example validation:
IF r_load.person_first_name IS NULL THEN
x_msg_data := ' "First name" cannot be null';
RAISE EXC_VALDN_ERR;
END IF;
-- Same validation for person_last_name here
-- Record Type:
person_rec.person_first_name := r_load.person_first_name;
person_rec.person_last_name := r_load.person_last_name;
person_rec.person_title := v_title;
person_rec.known_as := null;
person_rec.gender := v_gender;
person_rec.created_by_module := 'TCA_V2_API';
HZ_PARTY_V2PUB.create_person ( p_init_msg_list => FND_API.G_TRUE
, p_person_rec => person_rec
, x_party_id => x_party_id
, x_party_number => x_party_number
, x_profile_id => x_profile_id
, x_return_status => x_return_status
, x_msg_count => x_msg_count
, x_msg_data => x_msg_data);
msg_log('==========================');
msg_log('first name / last_name : '||r_load.person_first_name||' | '||r_load.person_last_name);
msg_log('x_return_status: '||x_return_status);
msg_log('x_msg_count: '||x_msg_count);
msg_log('x_msg_data: '||x_msg_data);
IF NVL(x_return_status, FND_API.G_RET_STS_ERROR) <> FND_API.G_RET_STS_SUCCESS THEN
IF NVL(x_msg_count, 0) > 1 THEN
FOR i IN 1..x_msg_count LOOP
x_msg_data := x_msg_data||i||'. '||substr(fnd_msg_pub.get(p_encoded => fnd_api.g_false ), 1, 255)||' , ';
msg_log(x_msg_data);
END LOOP;
END IF;
END IF;
msg_log('==========================');
EXCEPTION
WHEN OTHERS THEN
x_msg_data := 'EXC: '||NVL(x_msg_data, SQLERRM);
x_return_status := FND_API.G_RET_STS_ERROR;
END;
UPDATE xx_customer_info
SET status_flag = x_return_status
, error_message = x_msg_data
WHERE rowid = r_load.row_id;
END LOOP;
COMMIT;
msg_log ('Exit '||ERR_SOURCE);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
msg_log('ERROR : '||ERR_SOURCE||' : '||NVL(SQLERRM, x_msg_data));
errbuff := 'ERROR : '||ERR_SOURCE||' : '||NVL(SQLERRM, x_msg_data);
retcode := RTN_ERROR;
END create_customer;
It should return errors or success.
When I test and run this in anonymous block:
begin
XX_CUST_PKG.create_customer;
end;
I get error message PLS-00306: wrong number or types of arguments in call to 'CREATE_CUSTOMER'. I can't see clearly where this error is referring to. I only have 2 OUT parameters, it should only give errbuff (which is x_msg_data) and retcode which is RTN_SUCCESS, RTN_WARNING or RTN_ERROR (I have this declared as constants '0', '1', '2') to output.
This was rewritten from initial package to the above example code, so that it handles exceptions, and few things had to be modified, but now I'm confused when testing it.
What did I leave out?
Any help?
The error you get is a PL/SQL compilation error, as you can see the error code starts with PLS-XXXX.. So it is not returned from your procedure. You missed to send the variables to hold the values from your procedure (out arguments)
Declare
errbuf varchar2(4000);
retcode varchar2(10);
begin
XX_CUST_PKG.create_customer(errbuf,retcode);
--printing the values
DBMS_OUTPUT.PUT_LINE(retcode||' '||errbuf);
end;
/