I am executing the below procedure from SQL DEVELPER, I get an option to insert the input values for z_id & i_type however i_data is greyed out.
can a procedure with input param as collection cannot be executed from SQL
DEVELOPER tool ?
What am I missing here ? The code gets compiled but unable to execute it through SQL Developer
below is what I have done but this gives compilation error on Oracle 19c
create or replace type my_type AS OBJECT (
p_id number,
p_text varchar2 (100),
p_details clob);
/
create or replace type tab1 is table of my_type;
/
create or replace procedure vehicle_det (z_id in varchar2, i_type in varchar2, i_data in tab1)
IS
BEGIN
for i in 1..i_data.count
LOOP
if (i_type ='BMW')
THEN
UPDATE STOCK_DATA
set stock_id=i_data(i).p_id, stock_des=i_data(i).p_text, clearance=i_data(i).p_details where s_id=z_id ;
end if;
end loop;
end vehicle_det;
Below is the error, please provide your wisdom::::
**ERROR --ORA-06531 Reference to uninitialized collection **
Here's code that actually works. See how it is done.
Types and sample table:
SQL> create or replace type my_type AS OBJECT (
2 p_id number,
3 p_text varchar2 (100),
4 p_details clob);
5 /
Type created.
SQL> create or replace type tab1 is table of my_type;
2 /
Type created.
SQL> create table stock_data
2 (s_id number,
3 stock_id number,
4 stock_des varchar2(20),
5 clearance clob);
Table created.
SQL> insert into stock_data
2 select 1 s_id, 1 stock_id, 'Description' stock_Des, null clearance
3 from dual;
1 row created.
SQL>
Procedure:
SQL> create or replace procedure vehicle_det
2 (z_id in varchar2, i_type in varchar2, i_data in tab1)
3 IS
4 BEGIN
5 for i in 1..i_data.count LOOP
6 if i_type = 'BMW' THEN
7 UPDATE STOCK_DATA
8 set stock_id = i_data(i).p_id,
9 stock_des = i_data(i).p_text,
10 clearance = i_data(i).p_details
11 where s_id = z_id ;
12 end if;
13 end loop;
14 end vehicle_det;
15 /
Procedure created.
Testing: current table contents / run the procedure / see the result:
SQL> select * from stock_data;
S_ID STOCK_ID STOCK_DES CLEARANCE
---------- ---------- -------------------- ------------------------------
1 1 Description
SQL> declare
2 l_data tab1 := tab1();
3 begin
4 l_data.extend;
5 l_data(1) := my_type(1, 'This is BMW', 'Oh yes, this IS a BMW!');
6
7 vehicle_det(1, 'BMW', l_data);
8 end;
9 /
PL/SQL procedure successfully completed.
SQL> select * from stock_data;
S_ID STOCK_ID STOCK_DES CLEARANCE
---------- ---------- -------------------- ------------------------------
1 1 This is BMW Oh yes, this IS a BMW!
SQL>
Related
Write a function to insert the string in a table which will display the character of string like if we pass (KRISHNA it will display
K
R
I
S
H
N
A
) Inside the table.
Here's one option:
Sample table:
SQL> create table test (source_string varchar2(20), target_string varchar2(20));
Table created.
Procedure:
SQL> create or replace procedure p_test (par_string in varchar2) is
2 begin
3 insert into test (source_string, target_string)
4 select par_string,
5 regexp_replace(par_string, '(.)', '\1' ||chr(10))
6 from dual;
7 end;
8 /
Procedure created.
Testing:
SQL> exec p_test ('KRISHNA');
PL/SQL procedure successfully completed.
SQL> select * from test;
SOURCE_STRING TARGET_STRING
-------------------- --------------------
KRISHNA K
R
I
S
H
N
A
SQL>
If it has to be a function, then - as you see how to do it - you could have switched to it (the function) yourself, instead of insisting on someone else doing your homework.
Anyway:
SQL> create or replace function f_test (par_string in varchar2)
2 return varchar2
3 is
4 begin
5 return regexp_replace(par_string, '(.)', '\1' ||chr(10));
6 end;
7 /
Function created.
SQL> insert into test (source_string, target_string)
2 values ('IHCASAYBAS', f_test ('IHCASAYBAS'));
1 row created.
Result:
SQL> select * from test;
SOURCE_STRING TARGET_STRING
-------------------- --------------------
KRISHNA K
R
I
S
H
N
A
IHCASAYBAS I
H
C
A
S
A
Y
B
A
S
SQL>
I am creating a stored procedure in Oracle database that's resulting in error "ORA-01858: a non-numeric character was found where a numeric was expected".
My procedure is as below:
create or replace procedure testProc(
id IN VARCHAR2,
user IN VARCHAR2,
sender IN VARCHAR2
)
as
vCount number;
begin
select count(*) into vCount from table1 where id='12345'
if vCount=0
insert into table1 (id, user, sender, status) values (id, user, partner, status);
else
update table1 set status='ERR' where id='12345'
end if;
end procedure;
Error: ORA-01858: a non-numeric character was found where a numeric was expected
I tried replacing vCount as int that did not help. Also tried declaring vCount below sender IN VARCHAR2.
Can someone please tell what is correct way to use the above procedure.
Use a MERGE statement then you can do it in a single statement (rather than SELECT followed by either INSERT or UPDATE):
CREATE PROCEDURE testProc(
i_id IN table1.id%TYPE,
i_user IN table1."USER"%TYPE,
i_sender IN table1.sender%TYPE,
i_status IN table1.status%TYPE
)
AS
BEGIN
MERGE INTO table1 dst
USING (
SELECT '12345' AS id
FROM DUAL
) src
ON (src.id = dst.id)
WHEN MATCHED THEN
UPDATE SET status = 'Err'
WHEN NOT MATCHED THEN
INSERT (id, "USER", sender, status)
VALUES (i_id, i_user, i_sender, i_status);
END testProc;
/
db<>fiddle here
This code can't possibly return error you specified because
procedure is invalid (mising statement terminators; column name can't be USER because it is a keyword, reserved for currently logged user)
that error code is related to date issues, while - in your code - there's nothing that looks like a date
Therefore, it is impossible to help you with error you stated. Otherwise, consider NOT naming procedure's parameters the same as column names because that leads to various problems.
Something like this would work, but it is not related to error you got.
Sample table:
SQL> CREATE TABLE table1
2 (
3 id VARCHAR2 (5),
4 c_user VARCHAR2 (20),
5 partner VARCHAR2 (10),
6 sender VARCHAR2 (10),
7 status VARCHAR2 (5)
8 );
Table created.
SQL>
Procedure:
SQL> CREATE OR REPLACE PROCEDURE testProc (p_id IN VARCHAR2,
2 p_user IN VARCHAR2,
3 p_sender IN VARCHAR2)
4 AS
5 vCount NUMBER;
6 BEGIN
7 SELECT COUNT (*)
8 INTO vCount
9 FROM table1
10 WHERE id = p_id;
11
12 IF vCount = 0
13 THEN
14 INSERT INTO table1 (id,
15 c_user,
16 sender,
17 status)
18 VALUES (p_id,
19 p_user,
20 NULL,
21 'NEW');
22 ELSE
23 UPDATE table1
24 SET status = 'ERR'
25 WHERE id = p_id;
26 END IF;
27 END testproc;
28 /
Procedure created.
Testing:
SQL> EXEC testproc('12345', 'Little', 'Foot');
PL/SQL procedure successfully completed.
SQL> SELECT * FROM table1;
ID C_USER PARTNER SENDER STATU
----- -------------------- ---------- ---------- -----
12345 Little NEW
SQL> EXEC testproc('12345', 'Little', 'Foot');
PL/SQL procedure successfully completed.
SQL> SELECT * FROM table1;
ID C_USER PARTNER SENDER STATU
----- -------------------- ---------- ---------- -----
12345 Little ERR
SQL>
CREATE OR REPLACE PROCEDURE myStoredProcedure (idParam IN VARCHAR2,
outputParam OUT VARCHAR2)
AS
BEGIN
SELECT OUTPUTCOL INTO outputParam FROM MyTable WHERE ID = idParam;
END;
DECLARE
v_OutputResults VARCHAR2(20);
BEGIN
myStoredProcedure('123', v_OutputResults);
SELECT v_OutputResults AS ColumnResult FROM DUAL;
END;
If we understand your goal, you should be using a function, not a procedure:
First, we set up the example:
SQL> -- conn system/halftrack#pdb01
SQL> conn scott/tiger#pdb01
Connected.
SQL> --
SQL> CREATE TABLE my_table (
2 user_id number not null,
3 Name varchar2(10)
4 )
5 ;
Table created.
SQL> --
SQL> insert into my_table values (1,'Bob');
1 row created.
SQL> insert into my_table values (2,'Carol');
1 row created.
SQL> insert into my_table values (3,'Ted');
1 row created.
SQL> insert into my_table values (4,'Alice');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from my_table;
USER_ID NAME
---------- ----------
1 Bob
2 Carol
3 Ted
4 Alice
4 rows selected.
Now we create the function, then use it:
SQL> --
SQL> create or replace function my_function (id_param number)
2 return varchar2
3 is
4 v_name varchar2(10);
5 begin
6 select name
7 into v_name
8 from my_table
9 where user_id = id_param
10 ;
11 --
12 return v_name;
13 end;
14 /
Function created.
SQL> show errors
No errors.
SQL> --
SQL> select my_function(1) from dual;
MY_FUNCTION(1)
--------------------------------------------------------------------------------
Bob
1 row selected.
And clean up our example:
SQL> --
SQL> drop table my_table purge;
Table dropped.
No but you can do so using a stored function.
i have 2 stored procedures 1 is called A with the following impl
PROCEDURE A(p_id IN NUMBER, lic_cat_2 OUT varchar2,lic_cat_1 OUT varchar2,traffic_code OUT varchar2,lic_type OUT varchar2,emp_num OUT varchar2)
// Some LOGIC
end A ;
and PROCEDURE B which is a wrapper to proc A but i need to get other value with a query
PROCEDURE B(ph_id IN NUMBER, lic_cat_2 OUT varchar2,lic_cat_1 OUT varchar2,traffic_code OUT varchar2,lic_type OUT varchar2,emp_num OUT varchar2)
declare number phone_id
begin
select into phone_id parent_id from per_phones where phone_id= p_id
exec A(phone_id,lic_cat_2 OUT varchar2,lic_cat_1 OUT varchar2,traffic_code OUT varchar2,lic_type OUT varchar2,emp_num OUT varchar2);
END B;
but it gives me PLS-00103: Encountered the symbol “CREATE”
You're calling the A procedure in a wrong manner:
omit EXEC, it is a SQL*Plus command
omit parameters' description (IN/OUT, datatype) - pass only values
omit DECLARE; you need it in triggers or anonymous PL/SQL blocks, but not in stored procedures
by the way, variable name comes first, datatype next (for phone_id)
I'd suggest you to prefix parameters and variables with p_ (or par_) and l_ respectively (or any other prefix you want) to distinguish them from column names. Otherwise, it is easy to get confused.
also, use table aliases in your queries for the same reason
So:
CREATE OR REPLACE PROCEDURE B (p_ph_id IN NUMBER,
p_lic_cat_2 OUT VARCHAR2,
p_lic_cat_1 OUT VARCHAR2,
p_traffic_code OUT VARCHAR2,
p_lic_type OUT VARCHAR2,
p_emp_num OUT VARCHAR2)
IS
l_phone_id NUMBER;
BEGIN
SELECT p.parent_id
INTO l_phone_id
FROM per_phones p
WHERE p.phone_id = p_ph_id;
A (l_phone_id,
p_lic_cat_2,
p_lic_cat_1,
p_traffic_code,
p_lic_type,
p_emp_num);
END B;
As I don't have your tables, for example (to show how to do it) I used Scott's sample schema:
SQL> create or replace procedure a (par_deptno in number, par_dname out varchar2)
2 is
3 begin
4 select dname into par_dname from dept where deptno = par_deptno;
5 end;
6 /
Procedure created.
SQL>
SQL> create or replace procedure b (par_empno in number, par_dname out varchar2) is
2 l_deptno emp.deptno%type;
3 begin
4 select deptno into l_deptno from emp where empno = par_empno;
5
6 a(l_deptno, par_dname);
7 end;
8 /
Procedure created.
SQL>
SQL> set serveroutput on
SQL> declare
2 l_dname dept.dname%type;
3 begin
4 b (7654, l_dname);
5 dbms_output.put_line('Dname = ' || l_dname);
6 end;
7 /
Dname = SALES
PL/SQL procedure successfully completed.
SQL>
I have this procedure:
SQL> create or replace procedure KORELACJA (START IN DATE, END IN DATE) AS
2 BEGIN
3 SELECT T.City, Corr(T.Value, H.Value)
4 FROM TEMP T
5 INNER JOIN HUMIDITY H
6 on T.City = H.City
7 and T.mDate = H.mDate
8 WHERE T.mDate between to_date(START,'YYYY-MM-DD') and to_date(END,'YYYY-MM-DD')
9 GROUP BY T.City
10 END;
11 /
with error: ORA-06550: line 1, column 7:
Anyone knows how to fix this problem?
[EDIT]
SQL> show error procedure KORELACJA;
Errors for PROCEDURE KORELACJA:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/1 PLS-00428: an INTO clause is expected in this SELECT statement
Have a look at this example; read comments within the code.
I've created sample tables, just to make sure that the procedure code compiles.
SQL> create table temp (city varchar2(10), value number, mdate date);
Table created.
SQL> create table humidity (city varchar2(10), value number, mdate date);
Table created.
The procedure itself:
SQL> create or replace procedure korelacja
2 (p_start in date, p_end in date) --> renamed parameters
3 is
4 l_city temp.city%type; --> declared local variables for SELECT
5 l_corr number; -- statement's results
6 begin
7 select t.city, corr(t.value, h.value)
8 into l_city, l_corr --> missing INTO clause
9 from temp t join humidity h on t.city = h.city
10 and t.mdate = h.mdate
11 where t.mdate between p_start and p_end --> parameters already are DATEs; you don't
12 group by t.city; -- need TO_DATE against them
13 end;
14 /
Procedure created.
SQL>