Error while creating PL/SQL procedure - oracle

I am trying to create the procedure below with PL/SQL, but it shows a red cross on the procedure name but no error was displayed so can anyone tell me what's wrong with that code
create or replace procedure CREATE_DM_CLIENT(
V_C_ID VARCHAR2,
V_S_ID VARCHAR2,
V_A_ID VARCHAR2,
V_J IN VARCHAR2,
V_H IN VARCHAR2,
V_COM IN VARCHAR2,
V_COD OUT VARCHAR2)
is
code_erreur number;
lib_erreur varchar(200) ;
num number := 0;
BEGIN
SELECT SEQ_DEM.NEXTVAL
INTO NUM
FROM DUAL;
INSERT INTO DM_CLIENTS(DM_C_ID, C_ID, S_ID, A, J, H, D_S, C)
VALUES(num, V_C_ID, V_S_ID, V_A_ID, V_J, V_H, SYSDATE, V_C);
--update num_client set etat=1 where num=V_CLIENT_ID;
commit;
V_COD:='100';
EXCEPTION
WHEN OTHERS THEN
l_e := SQLERRM ;
C_L := SQLCODE ;
insert into l_table (ligne , module)
values ( to_char(CODE_ERREUR)||LIB_ERREUR ,
'CREATE_DM_CLIENT' ) ;
commit;
V_CODEREP:='109';
end create_dm_client;

Compilation errors for PROCEDURE SAC.CREATE_DM_CLIENT
Error: PLS-00201: identifier 'L_E' must be declared
Line: 33
Text: l_e := SQLERRM;
Error: PL/SQL: Statement ignored
Line: 33
Text: l_e := SQLERRM;
Error: PLS-00201: identifier 'C_L' must be declared
Line: 34
Text: C_L := SQLCODE;
Error: PL/SQL: Statement ignored
Line: 34
Text: C_L := SQLCODE;
Error: PLS-00201: identifier 'V_CODEREP' must be declared
Line: 40
Text: V_CODEREP := '109';
Error: PL/SQL: Statement ignored
Line: 40
Text: V_CODEREP := '109';
other errors i did not mentioned, was because I don't have table name and sequences.

The 3 mentioned variables are not declared.
...
is
v_coderep varchar2(3);
c_l varchar2(3)
l_e varchar2(1024);
...

Please define l_e, C_L and V_CODEREP variables in variable declaration section. for example -
l_e varchar(20);
C_L integer;
V_CODEREP varchar(3);

Related

Oracle PLSQL wrong number or types of arguments in call to 'BIND_ARRAY' in DBMS_SQL

I've written the below PLSQL block.
However when i execute it , i am getting following error.
Kindly tell me how to pass nested tables in the DBMS_SQL to
execute and generate the report.
Can we use DBMS_SQL to pass array value to bind
parameters ?
Or else do we have to use Execute Immediate only.
We are using DBMS_SQL for generating all the reports.
Error report -
ORA-06550: line 34, column 2:
PLS-00306: wrong number or types of arguments in call to 'BIND_ARRAY'
ORA-06550: line 34, column 2:
PL/SQL: Statement ignored
ORA-06550: line 35, column 2:
PLS-00306: wrong number or types of arguments in call to 'BIND_ARRAY'
ORA-06550: line 35, column 2:
declare
l_cursor number := dbms_sql.open_cursor;
l_ignore number;
q varchar2(32000);
o_desc_tab DBMS_SQL.desc_tab;
l_col_cnt number(10);
l_val VARCHAR2 (32767);
l_rec_no NUMBER;
l_col_sep VARCHAR2(25) := ',';
l_text VARCHAR2 (32767);
l_value VARCHAR2 (4000);
TYPE T_dc_code IS TABLE OF VARCHAR2(25);
A_dc_code T_dc_code;
TYPE T_bin_type IS TABLE OF VARCHAR2(25);
A_bin_type T_bin_type;
begin
q :='select col1, col2, col3, col4
from tabl1 wbm
inner join table2 wam
on wbm.dc_code=wam.dc_code
and wbm.dc_area=wam.dc_area
where wbm.dc_code MEMBER OF :P_DC_CODE
and wbm.BIN_TYPE MEMBER OF :P_BIN_TYPE
)';
dbms_sql.parse( l_cursor,q,dbms_sql.native );
A_dc_code.EXTEND(2);
A_dc_code(1) := '888';
A_dc_code(2) := '902';
A_bin_type.EXTEND(2);
A_bin_type(1) := 'R';
A_bin_type(2) := 'P';
dbms_sql.bind_array( l_cursor, ':P_DC_CODE', A_bin_type );
dbms_sql.bind_array( l_cursor, ':P_BIN_TYPE', A_dc_code );
DBMS_SQL.describe_columns (l_cursor, l_col_cnt, o_desc_tab);
FOR l_cl_cnt IN 1 .. o_desc_tab.COUNT
LOOP
DBMS_SQL.define_column (l_cursor, l_cl_cnt, l_val, 32767);
END LOOP;
l_ignore := dbms_sql.execute( l_cursor );
WHILE (DBMS_SQL.fetch_rows (l_cursor) > 0)
LOOP
DBMS_OUTPUT.PUT_LINE('COMING IN LOOP');
FOR l_rec_no IN 1 .. o_desc_tab.COUNT
LOOP
DBMS_SQL.COLUMN_VALUE (l_cursor, l_rec_no, l_value);
l_text := l_text || l_col_sep || l_value;
END LOOP;
END LOOP;
dbms_sql.close_cursor( l_cursor );
DBMS_OUTPUT.PUT_LINE('THE VALUE IS ---- '||l_text);
end;
/
Thanks
You have to use one of the pre-defined types, e.g. DBMS_SQL.varchar2_table, see Types for Scalar and LOB Collections.
Using your own TYPE T_bin_type IS TABLE OF VARCHAR2(25) is not possible
A_bin_type DBMS_SQL.varchar2_table;
BEGIN
A_bin_type(1) := 'R';
A_bin_type(2) := 'P';

Oracle pl/sql problem when trying to reference plsql table in query

I am getting a pls-201 error when I try to reference a plsql table record in a query.
Here is an example of the issue:
DECLARE
TYPE trxtypeinforec IS RECORD(
NAME ra_cust_trx_types.NAME%TYPE
);
TYPE trxtypeinfotab IS TABLE OF trxtypeinforec
INDEX BY PLS_INTEGER;
g_inv_type trxtypeinfotab;
l_result VARCHAR2 (100);
BEGIN
g_inv_type(1).NAME := 'Test';
SELECT g_inv_type(qry.ID).NAME
INTO l_result
FROM (SELECT 1 ID
FROM dual) qry;
END;
Error report - ORA-06550: line 15, column 23: PLS-00201: identifier
'QRY.ID' must be declared ORA-06550: line 15, column 23: PLS-00201:
identifier 'QRY.ID' must be declared ORA-06550: line 15, column 12:
PL/SQL: ORA-00904: : invalid identifier ORA-06550: line 15, column 5:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Retrieve the index from the SELECT first into a local variable and then assign the value from the associative array to l_result in a PL/SQL scope and not in an SQL scope:
DECLARE
TYPE trxtypeinforec IS RECORD(
NAME ra_cust_trx_types.NAME%TYPE
);
TYPE trxtypeinfotab IS TABLE OF trxtypeinforec INDEX BY PLS_INTEGER;
g_inv_type trxtypeinfotab;
idx PLS_INTEGER;
l_result ra_cust_trx_types.NAME%TYPE;
BEGIN
g_inv_type(1).NAME := 'Test';
SELECT 1
INTO idx
FROM DUAL;
l_result := g_inv_type(idx).NAME;
DBMS_OUTPUT.PUT_LINE( l_result );
END;
/
Outputs:
Test
db<>fiddle here
Please try using a cursor.
SET SERVEROUTPUT ON;
DECLARE
TYPE trxtypeinforec IS RECORD(
NAME ra_cust_trx_types.NAME%TYPE
);
TYPE trxtypeinfotab IS TABLE OF trxtypeinforec
INDEX BY PLS_INTEGER;
g_inv_type trxtypeinfotab;
l_result VARCHAR2 (100);
-- Query for retrieving index goes in the cursor or use existing cursor
CURSOR cur_id IS
SELECT 1 AS ID FROM DUAL;
BEGIN
-- Populate records here or put inside loop as required
g_inv_type(1).NAME := 'Test';
-- Loop through the cursor to get the relevant index
FOR rec in cur_id
LOOP
SELECT g_inv_type(rec.ID).NAME
INTO l_result
FROM DUAL;
dbms_output.put_line (l_result);
END LOOP;
END;
/
It will be helpful if we could get some more information on how the existing cursor is fetching index values.
Output:
Test
PL/SQL procedure successfully completed.

Dynamic select execution missing expression error

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;

Procedure calling gone bad - Statement Ignored

I have the following procedure to insert users in a table:
CREATE OR REPLACE PROCEDURE ELR_ADD_USER
(I_NAME IN VARCHAR2,
I_MORADA IN VARCHAR2,
I_BIRTHDATE IN DATE,
I_COUNTRY IN VARCHAR2,
O_ID OUT NUMBER,
O_ERROR_MSG OUT VARCHAR2)
IS
ERROR_NULL EXCEPTION;
BEGIN
IF I_NAME IS NULL OR
I_MORADA IS NULL OR
I_BIRTHDATE IS NULL OR
I_COUNTRY IS NULL THEN
RAISE ERROR_NULL;
END IF;
O_ID := ELR_seq_USER_ID.nextval;
IF O_ID IS NULL
RAISE ERROR_NULL;
END IF;
INSERT INTO ELR_USERS
VALUES (O_ID, I_NOME, I_MORADA, I_BIRTHDATE, I_COUNTRY);
EXCEPTION
WHEN ERROR_NULL THEN
O_ERROR_MSG := 'NULL FIELDS';
WHEN OTHERS THEN
O_ERROR_MSG := 'UNEXPECTED ERROR: '|| sqlerrm;
END;
/
I think the procedure and it's syntax are correct. However when I'm trying to call it with:
DECLARE
P_NAME VARCHAR2(50);
P_MORADA VARCHAR2(50);
P_BIRTHDATE DATE;
P_COUNTRY VARCHAR2(20);
P_ID NUMBER(20);
P_ERROR_MSG VARCHAR2(4000);
BEGIN
ELR_ADD_USER('ED WARNER','CENAS Street',SYSDATE,
'China', P_ID, P_ERROR_MSG);
IF P_ERROR_MSG IS NOT NULL THEN
DBMS_OUTPUT.PUT_LINE('ERROR: '||P_ERROR_MSG);
END IF;
END;
/
I get the following message:
Is there something wrong with the calling or the procedure itself?
ORA-06550 followed by PLS-00905 is clearly a compilation error. The procedure is in INVALID state.
Recompile the procedure, and use SHOW ERRORS to get the complete error details.
SHOW ERROR PROCEDURE RMS_MM.ELR_ADD_USER or simply SHOW ERRORS
For example,
SQL> CREATE OR REPLACE PROCEDURE TestProc
2 AS
3 vnum number;
4 BEGIN
5 vnum := vAnotherNum;
6 END;
7 /
Warning: Procedure created with compilation errors.
SQL> execute TestProc();
BEGIN TestProc(); END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object EXAMPLE.TESTPROC is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL> show error procedure TestProc;
Errors for PROCEDURE TESTPROC:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/1 PL/SQL: Statement ignored
5/9 PLS-00201: identifier 'VANOTHERNUM' must be declared

Using .count in for loop

I'm new to oracle. I've come across table functions. The code for the function is
CREATE TYPE t_tf_row AS OBJECT (
id NUMBER,
description VARCHAR2(50));
CREATE TYPE t_tf_tab IS TABLE OF t_tf_row;
CREATE OR REPLACE FUNCTION get_tab_tf (p_rows IN NUMBER) RETURN t_tf_tab AS
l_tab t_tf_tab := t_tf_tab();
BEGIN
FOR i IN 1 .. p_rows LOOP
l_tab.extend;
l_tab(l_tab.last) := t_tf_row(i, 'Description for ' || i);
END LOOP;
RETURN l_tab;
END;
Now, I want to create a procedure which will update the table type using for loop.
The code for the procedure is
create or replace procedure add_n_rows(n_rows in number) is
l_tab t_tf_tab := t_tf_tab();
begin
for i in t_tf_tab.count .. t_tf_tab.count + n_rows
loop
l_tab.extend;
l_tab(l_tab.last) := t_tf_row(i, 'Description for '|| i);
end loop;
end;
I'm getting error saying that COUNT should be declared.
ORA-06550: line 1, column 37:
PLS-00302: component 'COUNT' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Could you help me out in using the right procedure for .count in for loop.Thanks
You need to use the variable name not the type.
create or replace procedure add_n_rows(
n_rows in number)
is
l_tab t_tf_tab := t_tf_tab();
begin
for i in l_tab.count .. 1_tab.count + n_rows
loop
l_tab.extend;
l_tab(l_tab.last) := t_tf_row(i, 'Description for '|| i);
end loop;
end;
/

Resources