How to solved error executing procedure in Oracle PL/SQL - oracle

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;

Related

Call procedure with nested table as parameter

How code procedure with nested table parameter? In table test I need insert data from loop eg. 1,2,3...
plsql
Declare
TYPE code_nt is table of varchar2(10);
l_codes code_nt := code_nt();
begin ​
​FOR i IN 1..APEX_APPLICATION.G_F01.COUNT LOOP
l_codes.extend;
l_codes(i) := to_char(i);
​END LOOP;
//here call procedure
//PKG_EMP.INSERT_EMP(PAR_1);
end;
package:
create or replace PACKAGE PKG_EMP AS
TYPE code_nt is table of varchar2(10);
l_codes code_nt := code_nt();
procedure INSERT_EMP (PAR_1 code_nt);
END;
create or replace PACKAGE BODY PKG_EMP AS
procedure INSERT_EMP (PAR_1 code_nt) AS
BEGIN
INSERT INTO test (ID) VALUES (value from code_nt);
END;
end;
Your code will not work as code_nt is a locally defined type in both your PL/SQL function and the PL/SQL anonymous block and despite having the same name and signature they are different data types.
You need to use the same data type in both:
Declare
l_codes PKG_EMP.code_nt := PKG_EMP.code_nt();
begin ​
FOR i IN 1..APEX_APPLICATION.G_F01.COUNT LOOP
l_codes.extend;
l_codes(i) := to_char(i);
-- or
-- l_codes(i) := TO_CHAR( APEX_APPLICATION.G_F01(i) );
​END LOOP;
PKG_EMP.INSERT_EMP(l_codes);
END;
/
You can declare your package as:
CREATE PACKAGE PKG_EMP AS
TYPE code_nt is table of varchar2(10);
PROCEDURE INSERT_EMP (PAR_1 code_nt);
END;
/
CREATE PACKAGE BODY PKG_EMP AS
procedure INSERT_EMP (PAR_1 code_nt) AS
BEGIN
FORALL i IN 1 .. par_1.COUNT
INSERT INTO test (ID) VALUES ( par_1(i) );
END;
END;
/
db<>fiddle here

PLS-00049: bad bind variable 'D_DEPT_ID' in toad

I created procedure with substitution variable in Toad for Oracle but its giving me error
"PLS-00049: bad bind variable 'D_DEPT_ID'"
Procedure Code:
CREATE OR REPLACE PROCEDURE add_dept
IS
dept_id dept.deptno%TYPE;
dept_name dept.dname%TYPE;
BEGIN
dept_id := :d_dept_id;
dept_name := ':d_ name';
INSERT INTO dept(deptno,dname) VALUES (dept_id,dept_name);
DBMS_OUTPUT.PUT_LINE (' INSERTED ' || SQL%ROWCOUNT || ' ROW ');
END;
You cannot place bind variables inside of procedure or function code. To accomplish your task, you must pass the values in as parameters of the procedure at runtime.
CREATE OR REPLACE PROCEDURE add_dept(dept_id dept.deptno%TYPE, dept_name dept.dname%TYPE) IS
BEGIN
INSERT INTO dept(deptno,dname) VALUES (dept_id,dept_name);
DBMS_OUTPUT.PUT_LINE (' INSERTED ' || SQL%ROWCOUNT || ' ROW ');
END;
Then at runtime, in your anonymous block or calling code, you pass the values in from the end user..
BEGIN
add_date(:d_dept_id, :d_dept_name);
END;

Commit or handle rollback in stored procedure after insertions are done?

Optimal way to handle an error in stored procedure that only makes inserts?
I have a procedure like this:
PROCEDURE INSERT_TO_TABLES (VAL1 IN NUMBER, VAL2 IN NUMBER, RESULT OUT NUMBER)
IS
BEGIN
INSERT INTO TABLE_1 (A_COLUMN) VALUES (VAL1);
INSERT INTO TABLE_2 (B_COLUMN) VALUES (VAL2);
COMMIT;
END;
How could I make this stored procedure optimal enough to handle a rollback and raise an exception to catch from the application (C# try/catch) if only 1 of those inserts throws an error? Return out value true if everything is ok or false if an error happened?
SQLERRM and SQLCODE functions may be used :
CREATE OR REPLACE PROCEDURE INSERT_TO_TABLES (VAL1 IN NUMBER, VAL2 IN NUMBER, RESULT OUT
NUMBER, RESULT_ERR OUT VARCHAR2 )
IS
v_err_code number := SQLCODE;
v_err_txt varchar2(4000) := SQLERRM;
Begin
Begin
INSERT INTO TABLE_1 (A_COLUMN) VALUES (VAL1);
INSERT INTO TABLE_2 (B_COLUMN) VALUES (VAL2);
Exception When Others then
RESULT_ERR := v_err_code||' '||v_err_txt;
End;
If ( nvl(v_err_code,0)<0 ) Then
ROLLBACK;
Else
RESULT_ERR :='Committed with success...';
COMMIT;
End If;
End;

calling stored procedure from anonymous block

I have problem reading result from plsql stored procedure written in sql developer on Oracle 11gr2 database on local machine.
This is my table:
create table MY_TEST_TABLE
(employee_id NUMBER(6)
,first_name VARCHAR2(20)
,last_name VARCHAR2(25)
,email VARCHAR2(25)
,phone_number VARCHAR2(20));
This is procedure declaration:
create or replace PACKAGE TEST_PACKAGE AS
procedure test_procedure (i_id in number,
o_data out sys_refcursor);
END TEST_PACKAGE;
This is body:
create or replace PACKAGE BODY TEST_PACKAGE AS
procedure test_procedure (i_id in number,
o_data out sys_refcursor) AS
BEGIN
open o_data for
select employee_id,
first_name,
last_name,
email,
phone_number
from my_test_table
where EMPLOYEE_ID = i_id;
close o_data;
END test_procedure;
END TEST_PACKAGE;
And this is anonymous block call:
SET serveroutput on
DECLARE
in_id number;
my_cursor sys_refcursor;
current_record my_test_table%ROWTYPE;
BEGIN
in_id := 1;
test_package.test_procedure(in_id, my_cursor);
open my_cursor;
LOOP
FETCH my_cursor INTO current_record;
EXIT WHEN my_cursor%NOTFOUND;
dbms_output.put_line(' - out - ' || current_record.employee_id);
END LOOP;
END;
I am getting error:
Error starting at line : 2 in command -
DECLARE
in_id number;
my_cursor sys_refcursor;
current_record my_test_table%ROWTYPE;
BEGIN
in_id := 1;
test_package.test_procedure(in_id, my_cursor);
open my_cursor;
LOOP
FETCH my_cursor INTO current_record;
EXIT WHEN my_cursor%NOTFOUND;
dbms_output.put_line(' - out - ' || current_record.employee_id);
END LOOP;
END;
Error report -
ORA-06550: line 8, column 5:
PLS-00382: expression is of wrong type
ORA-06550: line 8, column 5:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Can someone explain what is wrong?
Tnx!
The cursor is opened in the procedure, so you don't need to, and can't, open it directly in your anonymous block. Well, it should be open, but you're also closing it in the procedure. Remove the close from the procedure, and the open from the block:
create or replace PACKAGE BODY TEST_PACKAGE AS
procedure test_procedure (i_id in number,
o_data out sys_refcursor) AS
BEGIN
open o_data for
select employee_id,
first_name,
last_name,
email,
phone_number
from my_test_table
where EMPLOYEE_ID = i_id;
-- close o_data;
END test_procedure;
END TEST_PACKAGE;
/
And:
DECLARE
in_id number;
my_cursor sys_refcursor;
current_record my_test_table%ROWTYPE;
BEGIN
in_id := 1;
test_package.test_procedure(in_id, my_cursor);
-- open my_cursor;
LOOP
FETCH my_cursor INTO current_record;
EXIT WHEN my_cursor%NOTFOUND;
dbms_output.put_line(' - out - ' || current_record.employee_id);
END LOOP;
END;
/
SQL Fiddle - just add data...

ORA-06530: Reference to uninitialized composite

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 );

Resources