Oracle procedure (failure od date format) - oracle

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>

Related

Stored procedure with select count(*) and use count in IF statement

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>

SQL Developer ERROR: Reference to uninitialized collection

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>

PLS-00306: wrong number or types of arguments in call to error

I get this error when calling the procedure. I am trying to do this practice.
Create a procedure called find_region_and_currency to fetch and return the currency and region in which a country is located.
Pass COUNTRY_NAME as an IN parameter and use a user-defined record as an OUT parameter that returns the country name, its region and currency.
I tried old answer from here but I didnt do it. Could you please help me?
CREATE OR REPLACE PACKAGE traveler_assistance_package
IS
TYPE country_rec IS RECORD (
country_name COUNTRIES.COUNTRY_NAME%TYPE,
region COUNTRIES.REGION_ID%TYPE,
currency COUNTRIES.CURRENCY_CODE%TYPE);
PROCEDURE find_region_and_currency
(p_country_name IN COUNTRIES.country_name%TYPE,
p_country_rec OUT country_rec);
END traveler_assistance_package;
CREATE OR REPLACE package body traveler_assistance_package
IS
PROCEDURE find_region_and_currency
(p_country_name IN countries.country_name%TYPE,
p_country_rec OUT country_rec)
IS
BEGIN
SELECT country_name, region_id, currency_code INTO p_country_rec
FROM COUNTRIES
where COUNTRY_NAME = p_country_name;
DBMS_OUTPUT.PUT_LINE('Country Name:'||p_country_rec.country_name ||
'Region:' || p_country_rec.region ||
'Currency:' || p_country_rec.currency);
END;
END traveler_assistance_package;
You didn't post what went wrong (which part of code); anyway, here you go.
Sample table:
SQL> create table countries
2 (country_name varchar2(20),
3 region_id varchar2(20),
4 currency_code varchar2(20));
Table created.
SQL> insert into countries values ('Croatia', 'A', 'kn');
1 row created.
Package:
SQL> CREATE OR REPLACE PACKAGE traveler_assistance_package
2 IS
3 TYPE country_rec IS RECORD (
4 country_name COUNTRIES.COUNTRY_NAME%TYPE,
5 region COUNTRIES.REGION_ID%TYPE,
6 currency COUNTRIES.CURRENCY_CODE%TYPE);
7 PROCEDURE find_region_and_currency
8 (p_country_name IN COUNTRIES.country_name%TYPE,
9 p_country_rec OUT country_rec);
10 END traveler_assistance_package;
11 /
Package created.
Package body:
SQL> CREATE OR REPLACE package body traveler_assistance_package
2 IS
3 PROCEDURE find_region_and_currency
4 (p_country_name IN countries.country_name%TYPE,
5 p_country_rec OUT country_rec)
6 IS
7 BEGIN
8 SELECT country_name, region_id, currency_code INTO p_country_rec
9 FROM COUNTRIES
10 where COUNTRY_NAME = p_country_name;
11
12 --dbms_output.put_line('Printing from FIND_REGION_AND_CURRENCY');
13 --DBMS_OUTPUT.PUT_LINE('Country Name:'||p_country_rec.country_name ||
14 -- ' Region:' || p_country_rec.region ||
15 -- ' Currency:' || p_country_rec.currency);
16 END;
17 END traveler_assistance_package;
18 /
Package body created.
Testing:
SQL> set serveroutput on;
SQL> declare
2 l_out traveler_assistance_package.country_rec;
3 begin
4 traveler_assistance_package.find_region_and_currency ('Croatia', l_out);
5
6 dbms_output.put_line('Printing from anonymous PL/SQL block');
7 dbms_output.put_line(l_out.country_name ||', '|| l_out.currency);
8 end;
9 /
Printing from anonymous PL/SQL block
Croatia, kn
PL/SQL procedure successfully completed.

fetching table data into a table using cursor

I have a table called phonebook and it has two columns (firstName, LastName). I want to create a table of lastName index by firstName using cursor, and I wrote this code:
CREATE OR REPLACE PROCEDURE proc1 AS
TYPE tableNames IS TABLE OF VARCHAR2(20) INDEX BY VARCHAR(20);
v1 tableNames;
v_firstName PHONEBOOK.FIRSTNAME%TYPE;
v_lastName PHONEBOOK.LASTNAME%TYPE;
CURSOR c_name IS SELECT FIRSTNAME, LASTNAME FROM PHONEBOOK;
BEGIN
OPEN c_name;
LOOP
FETCH c_name INTO v_firstName, v_lastName;
EXIT WHEN c_name%NOTFOUND;
v1(v_firstName) := v_lastName;
END LOOP;
FOR idx IN v1.FIRST..v1.LAST
LOOP
DBMS_OUTPUT.PUT_LINE (v1(idx));
END LOOP;
CLOSE c_name;
END;
/
It has been successfully compiled. When I run this procedure it should print lastNames which stored in the tableNames but it gave me an error:
ORA-06502 "PL/SQL: numeric or value error"
Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.
Please help me to solve this problem
Not FOR, but WHILE. Also, I used cursor FOR loop as a source; easier to write & maintain.
SQL> create table phonebook (firstname varchar2(10), lastname varchar2(10));
Table created.
SQL> insert into phonebook
2 select 'Little', 'Foot' from dual union all
3 select 'Mc' , 'Donalds' from dual;
2 rows created.
SQL> create or replace procedure proc1 as
2 type tablenames is table of varchar2(10) index by varchar2(10);
3 v1 tablenames;
4 idx varchar2(10);
5 begin
6 for cur_r in (select firstname, lastname
7 from phonebook
8 )
9 loop
10 v1(cur_r.firstname) := cur_r.lastname;
11 end loop;
12
13 idx := v1.first;
14 while idx is not null loop
15 dbms_output.put_line(v1(idx));
16 idx := v1.next(idx);
17 end loop;
18 end;
19 /
Procedure created.
SQL> exec proc1;
Foot
Donalds
PL/SQL procedure successfully completed.
SQL>

How to execute 2 Store Procedures with conditions

I want to RUN SP2 inside SP1. The SP2 inserts several data into a table, one of those data is actual date.
So, i want that SP2 only execute if in the column date, the date is within the last 10 days.
It´s possible?
Thanks
Here's an example.
First, create a table and insert some sample rows:
SQL> create table my_tbl
2 (id number,
3 my_col date
4 );
Table created.
SQL> insert into my_tbl (id, my_col)
2 -- more than 10 days ago
3 select 1, date '2018-05-25' from dual union all
4 -- less than 10 days ago
5 select 2, date '2018-09-01' from dual;
2 rows created.
Create two procedures; SP_1 is supposed to call SP_2 if condition is met. I'm looping through both rows in the table; one row's date value is OK, another one isn't.
SQL> create or replace procedure sp_2 as
2 begin
3 dbms_output.put_line('...I am in SP_2 now');
4 end;
5 /
Procedure created.
SQL> create or replace procedure sp_1 as
2 begin
3 for cur_r in (select my_col from my_tbl order by id) loop
4 dbms_output.put_line('date value = ' || to_char(cur_r.my_col, 'yyyy-mm-dd'));
5 if cur_r.my_col >= trunc(sysdate) - 10 then
6 dbms_output.put_line('...calling SP_2');
7 sp_2;
8 else
9 dbms_output.put_line('...date condition failed - not calling SP_2');
10 end if;
11 end loop;
12 end;
13 /
Procedure created.
Testing:
SQL> set serveroutput on
SQL> begin
2 sp_1;
3 end;
4 /
date value = 2018-05-25
...date condition failed - not calling SP_2
date value = 2018-09-01
...calling SP_2
...I am in SP_2 now
PL/SQL procedure successfully completed.

Resources