Using 2 explicit cursors. - oracle

*/I am trying to use 2 explicit cursors, it shows these errors
{:ERROR at line 42:
ORA-06550: line 42, column 1:
PLS-00306: wrong number or types of arguments in call to 'PUT_LINE'
ORA-06550: line 42, column 1:
PL/SQL: Statement ignored } */
declare
v_CITY AIRPORT.CITY%TYPE;
v_ARRIVAL_TIME SCHEDULE.ARRIVAL_TIME%TYPE;
v_fnumber FLIGHT.FNUMBER%TYPE;
v_CITY1 AIRPORT.CITY%TYPE;
v_ARRIVAL_TIME1 SCHEDULE.ARRIVAL_TIME%TYPE;
v_fnumber1 FLIGHT.FNUMBER%TYPE;
/* First cursor */
CURSOR get_tables IS
select airp2.CITY , S. ARRIVAL_TIME,S.fnumber
from schedule S, FLIGHT F, airport airp1, airport airp2
where airp1.apcode = DEPARTURE_APCODE and airp2.apcode = ARRIVAL_APCODE AND ARRIVAL_APCODE ='BWI'and S.FNUMBER= F.FNUMBER AND
TO_CHAR(TRUNC(S.DEPARTURE_TIME)) = date'2017-11-12'
ORDER BY airp1.CITY, ARRIVAL_TIME ;
/* Second cursor */
CURSOR get_columns IS
select DISTINCT airp2.CITY , S. DEPARTURE_TIME,S.fnumber
from schedule S, FLIGHT F, airport airp1,FLIGHT_RESERVATION FL, airport airp2
where airp1.apcode = ORIGIN_APCODE and airp2.apcode = DESTINATION_APCODE AND ORIGIN_APCODE ='BWI'and S.FNUMBER= F.FNUMBER AND
TO_CHAR(TRUNC(S.DEPARTURE_TIME)) = date'2017-11-12'
ORDER BY airp2.CITY, DEPARTURE_TIME ;
BEGIN
-- Open first cursor
OPEN get_tables;
LOOP
FETCH get_tables INTO v_CITY, v_ARRIVAL_TIME, v_fnumber;
-- Open second cursor
OPEN get_columns;
LOOP
FETCH get_columns INTO v_CITY1, v_ARRIVAL_TIME1, v_fnumber1;
DBMS_output.put_line(v_CITY1, v_ARRIVAL_TIME1, v_fnumber1);
CLOSE get_tables;
END LOOP;
CLOSE get_columns;
END LOOP;
END;

DBMS_OUTPUT.PUT_LINE takes only one argument, so to output multiple values you have to convert them to character strings and concatenate them together. Change your PUT_LINE call to
DBMS_output.put_line('CITY1=' || TO_CHAR(v_CITY1) ||
' ARRIVAL_TIME=' || TO_CHAR(v_ARRIVAL_TIME1) ||
' FNUMBER=' || TO_CHAR(v_fnumber1));
Best of luck.

Related

Show the output of a procedure in Oracle

The procedure uses the previous function to display the list of the products: num, designation and mention on the application.
SET SERVEROUTPUT ON;
CREATE OR REPLACE FUNCTION STORE(num_produit IN INTEGER) RETURN VARCHAR AS
N INTEGER := 0;
incre INTEGER := 0;
BEGIN
SELECT SUM(qte) INTO N FROM Ligne_Fact WHERE num_produit = produit;
IF N > 15 THEN
RETURN 'fort';
ELSIF N > 11 THEN
RETURN 'moyen';
END IF;
RETURN 'faible';
END;
/
CREATE OR REPLACE PROCEDURE SHOW_PRODUITS IS
SOME_VAR VARCHAR2(256);
BEGIN
SELECT num, designation, STORE(num) INTO SOME_VAR FROM Produit;
dbms_output.enable();
dbms_output.put_line('result : '|| SOME_VAR);
END;
/
BEGIN
SHOW_PRODUITS;
END;
/
I am sure that all the tables are filled with some dummy data, but I am getting the following error:
Function STOCKER compiled
Procedure AFFICHER_PRODUITS compiled
LINE/COL ERROR
--------- -------------------------------------------------------------
4/4 PL/SQL: SQL Statement ignored
4/56 PL/SQL: ORA-00947: not enough values
Errors: check compiler log
Error starting at line : 28 in command -
BEGIN
AFFICHER_PRODUITS;
END;
Error report -
ORA-06550: line 2, column 5:
PLS-00905: object SYSTEM.SHOW_PRODUITS is invalid
ORA-06550: line 2, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
The first major mistake you've made is to create your objects in SYSTEM schema. It, just like SYS, are special and should be used only for system maintenance. Create your own user and do whatever you're doing there.
As of your question: select returns 3 values, but you're trying to put them into a single some_var variable. That won't work. Either add another local variables (for num and designation), or remove these columns from the select:
CREATE OR REPLACE PROCEDURE SHOW_PRODUITS IS
SOME_VAR VARCHAR2(256);
BEGIN
SELECT STORE(num) INTO SOME_VAR FROM Produit; --> here
dbms_output.enable();
dbms_output.put_line('result : '|| SOME_VAR);
END;
/
Code, as you put it, presumes that produit contains a single record (it can't be empty nor it can have 2 or more rows because you'll get various errors).
Maybe you wanted to access all rows; in that case, consider using a loop, e.g.
CREATE OR REPLACE PROCEDURE SHOW_PRODUITS IS
SOME_VAR VARCHAR2(256);
BEGIN
FOR cur_r IN (SELECT num, designation, STORE(num) some_var FROM Produit) LOOP
dbms_output.put_line(cur_r.num ||', '|| cur_r.designation ||', result : '|| cur_r.some_var);
END LOOP;
END;
/
Then
set serveroutput on
BEGIN
SHOW_PRODUITS;
END;
/
You are trying to compile some stored routine which calls another stored routine named AFFICHER_PRODUITS and that routine calls SHOW_PRODUITS but SHOW_PRODUITS does not compile, hence the error. (By the way, it is recommended not to create your own stored routines in the SYSTEM schema.)
SHOW_PRODUITS does not compile because of this line:
SELECT num, designation, STORE(num) INTO SOME_VAR FROM Produit;
It appears that you want to get the query results as a string. In order to do that, you need to concatenate the column values, i.e.
SELECT num || designation || STORE(num) INTO SOME_VAR FROM Produit;
Of-course if all you want to do is display the query results, using DBMS_OUTPUT, you can declare a separate variable for each column.
CREATE OR REPLACE PROCEDURE SHOW_PRODUITS IS
SOME_NUM Produit.num%type;
SOME_DES Produit.designation%type;
SOME_VAR VARCHAR2(6);
BEGIN
SELECT num
,designation
,STORE(num)
INTO SOME_NUM
,SOME_DES
,SOME_VAR
FROM Produit;
dbms_output.enable();
dbms_output.put_line('result : ' || SOME_NUM || SOME_DES || SOME_VAR);
END;
Note that if the query returns more than one row, you will [probably] need to use a cursor.
CREATE OR REPLACE PROCEDURE SHOW_PRODUITS IS
SOME_NUM Produit.num%type;
SOME_DES Produit.designation%type;
SOME_VAR VARCHAR2(6);
--
CURSOR c1 IS
SELECT num, designation, STORE(num) FROM Produit;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO SOME_NUM, SOME_DES, SOME_VAR;
EXIT WHEN c1%NOTFOUND;
dbms_output.put_line('result : ' || SOME_NUM || SOME_DES || SOME_VAR);
END LOOP;
CLOSE c1;
END;

Simple common error ORA-06550 in PL/SQL cursor

This is simple PL/SQL block and I have very simple error, ORA-06550 but I can't find it, pls Help me to solve this error..........
Question: Display category wise prize of most costly item
create table menu
(
item_id number primary key,
name_ varchar2(20),
prize number,
category varchar(15)
);
create table order_
(
o_id number primary key,
item_id number references menu(item_id),
table_no number,
qty number
);
SQL> declare
2 cursor data1 is select max(prize) as "prize_", category
3 from menu
4 group by category;
5
6 cursor data2(pr number, cat varchar(15)) is
7 select prize, name_, category
8 from menu
9 where prize = pr and category = cat;
10
11
12 data1_cat varchar(15);
13 data1_pri number;
14
15 data2_cat varchar(15);
16 data2_pri number;
17 data2_name varchar(15);
18 begin
19 open data1;
20 open data2;
21
22 fetch data1 into data1_pri, data1_cat;
23 while data1%found
24 loop
25 fetch data2(data1_pri, data1_cat) into data2_pri, data2_name, data2_cat;
26 while data2%found
27 loop
28 dbms_output.put_line(data2_name || ' ' || data2_pri || ' ' || data2_cat);
29 fetch data2(data1_pri, data1_cat) into data2_pri, data2_name, data2_cat;
30 end loop;
31
32
33 fetch data1 into data1_pri, data1_cat;
34 end loop;
35 close data2;
36 close data1;
37 end;
38 /
Error is blow
ERROR at line 6:
ORA-06550: line 6, column 40:
PLS-00103: Encountered the symbol "(" when expecting one of the following:
:= . ) , # % default character
The symbol ":=" was substituted for "(" to continue.
ORA-06550: line 25, column 20:
PLS-00103: Encountered the symbol "(" when expecting one of the following:
. into bulk
ORA-06550: line 25, column 80:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( , % from
ORA-06550: line 29, column 24:
PLS-00103: Encountered the symbol "(" when expecting one of the following:
. into bulk
ORA-06550: line 29, column 84:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( , % from
ORA-06550: line 35, column 5:
PLS-00103: Encountered the symbol "CLOSE" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
So your anonymous block has way too much mess in it. ORA-06550 is not your problem, the PLS-00103 is and together with ORA-06550 it marks a place where you messed up your code.
First off, your cursor declaration is not according to syntax scheme in documentation. cursor data2(pr number, cat varchar(15)) should be cursor data2(pr number, cat varchar), notice how your first error says ORA-06550: line 6, column 40: PLS-00103: Encountered the symbol "(" when expecting one of the following: := . ) , # % default character, because on line 6 it encountered ( as part of varchar(15) which shouldn't be there.
Your cursor handling is all over the place. Cursor parameters are provided when cursor is being opened not when it is fetched, also you are opening and closing cursor data2 outside of the loop which means that data in the loop are not changed while fetched. Fetch syntax is plain wrong as I mentioned before, no parameters are provided to cursor when data are fetched. This all can be fixed but I would like to propose an cleaner and easier alternative how to call your cursors (unless you have to use open, fetch, close in your assignment):
declare
cursor data1 is select max(prize) as "prize_", category
from menu
group by category;
cursor data2(pr number, cat varchar) is
select prize, name_, category
from menu
where prize = pr and category = cat;
begin
for c in data1 loop
for i in data2(c."prize_", c.category) loop
dbms_output.put_line(i.name_ || ' ' || i.prize || ' ' || i.category);
end loop;
end loop;
end;
/
Here is fixed cursor usage of your original code and I advice you to read more into cursors for example here, I added comments to provide a better look into what is happening in the code:
declare
cursor data1 is select max(prize) as "prize_", category
from menu
group by category;
cursor data2(pr number, cat varchar) is
select prize, name_, category
from menu
where prize = pr and category = cat;
data1_cat varchar(15);
data1_pri number;
data2_cat varchar(15);
data2_pri number;
data2_name varchar(15);
begin
-- Open cursor data1 and start looping over data in cursor
open data1;
loop
-- Fetch cursor data1 values into variables
fetch data1 into data1_pri, data1_cat;
-- Check if cursor provided data, if not exit loop
exit when data1%notfound;
-- Open cursor data2 with parameters from variables filled with data from cursor data1 and start looping over data in cursor
open data2(data1_pri, data1_cat);
loop
-- Fetch cursor data2 values into variables
fetch data2 into data2_pri, data2_name, data2_cat;
-- Check if cursor provided data, if not exit loop
exit when data2%notfound;
-- Handle variables as needed
dbms_output.put_line(data2_name || ' ' || data2_pri || ' ' || data2_cat);
end loop;
-- Close cursor data2 as new cursor will be opened in next loop and without closing it would lead to ORA-06511: PL/SQL: cursor already open
close data2;
end loop;
-- Close cursor data1 as good practice and possibly to avoid ORA-01000: maximum open cursors exceeded
close data1;
end;
/

Run stored procedure in SQL Developer

I have procedure with params:
procedure GetReceipt(iPaymentID in number
,oReceipt out sys_refcursor
,oReceiptItems out sys_refcursor);
I try to run this my anonymous block:
SET serveroutput on;
DECLARE
oReceipt sys_refcursor;
oReceiptItems sys_refcursor;
BEGIN
API.MOD.GetReceipt(4209735, oReceipt, oReceiptItems);
dbms_output.put_line('oReceipt: ' || oReceipt);
dbms_output.put_line('oReceiptItems: ' || oReceiptItems);
END;
I get this error:
Error report:
ORA-06550: Строка 6, столбец 24:
PLS-00306: wrong number or types of arguments in call to '||'
ORA-06550: Строка 6, столбец 3:
PL/SQL: Statement ignored
ORA-06550: Строка 7, столбец 24:
PLS-00306: wrong number or types of arguments in call to '||'
ORA-06550: Строка 7, столбец 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
How call this procedure? Where my mistake?
You can use bind variables to store the cursors and PRINT to print them:
VARIABLE receipt REFCURSOR;
VARIABLE receiptitems REFCURSOR;
BEGIN
API.MOD.GetReceipt(4209735, :receipt, :receiptitems);
END;
/
PRINT receipt;
PRINT receiptitems;
Where my mistake?
A cursor is a named pointer to a private SQL area that stores information for processing a specific query. It does not make sense to concatenate a pointer to something internal to the database with a string.
If you want to display the values in your PL/SQL block then you will need to loop through each record of the cursor and get the individual column values for that record and then use DBMS_OUTPUT to display them:
SET serveroutput on;
DECLARE
oReceipt sys_refcursor;
oReceiptItems sys_refcursor;
col1 RECEIPT_TABLE.COL1%TYPE; -- Same data type as COL1 of the RECEIPT_TABLE table
col2 RECEIPT_TABLE.COL2%TYPE; -- Same data type as COL2 of the RECEIPT_TABLE table
col3 RECEIPT_TABLE.COL3%TYPE; -- Same data type as COL3 of the RECEIPT_TABLE table
rec RECEIPT_ITEMS_TABLE%ROWTYPE; -- Assumes the cursor is returning all the columns from
-- the RECEIPT_ITEMS_TABLE table
BEGIN
API.MOD.GetReceipt(4209735, oReceipt, oReceiptItems);
dbms_output.put_line('oReceipt:');
LOOP
FETCH oReceipt INTO col1, col2, col3; -- Store the values from the current record
EXIT WHEN oReceipt%NOTFOUND; -- Stop if the end of the cursor has been reached
DBMS_OUTPUT.PUT_LINE( col1 || ' ' || col2 || ' ' || col3 );
-- Output the values
END LOOP;
dbms_output.put_line('oReceiptItems:');
LOOP
FETCH oReceiptItems INTO rec; -- Fetch the current row into a record
EXIT WHEN oReceipt%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( rec.colA || ' ' || rec.colB || ' ' || rec.colC );
END LOOP;
END;
/
sys_refcursor returns record set, may not be just a column.
So, you can not message it as a classical string with dbms_output.put_line. There should exists some columns(sub-components) of this argument in your routine like oReceiptItems.col_a or oReceiptItems.col_b so that you could message by these columns as strings with dbms_output.put_line.

Error trying to print Collection variable by index

Can anyone identify what is wrong with the following code. specifically the first dbms_output line. The second one prints fine. But first one gives this error:
Error at line 2
ORA-06550: line 15, column 53:
PLS-00201: identifier 'MYCOLL' must be declared
ORA-06550: line 15, column 1:
PL/SQL: Statement ignored
DECLARE
CURSOR c1
IS
SELECT sub_provider_address_id sub_id, phone, extension
FROM sub_provider_address;
TYPE coll_type IS TABLE OF c1%ROWTYPE;
my_coll coll_type;
BEGIN
OPEN c1;
FETCH c1
BULK COLLECT INTO my_coll;
dbms_output.put_line(' my_coll first row id has '|| mycoll(1).phone );
dbms_output.put_line(' my_coll now has '|| my_coll.last );
END;
You're declaring the variable as my_coll:
my_coll coll_type;
And on the line that's erroring you're referring to it as mycoll:
dbms_output.put_line(' my_coll first row id has '|| mycoll(1).phone );
So you're just missing an underscore, and it should be:
dbms_output.put_line(' my_coll first row id has '|| my_coll(1).phone );
Your coll_type is not an associated array type.
you have to use something like this:
TYPE coll_type IS TABLE OF c1%ROWTYPE index by pls_integer;
Use this as an example:
declare
cursor c1 is
select 1 id from dual
;
type coll_type is table of c1%ROWTYPE index by pls_integer;
l_coll_type coll_type;
begin
open c1;
fetch c1 bulk collect into l_coll_type;
close c1;
dbms_output.put_line('Output:' || l_coll_type(1).id);
end;
Output:1

Dynamic column name using cursor in Oracle PLSQL

I need to generate the column name dynamically in loop and access the column in oracle table using PLSQL. How do I do that?
DECLARE
varValue VARCHAR(20);
CURSOR c IS
SELECT * FROM TEST1;
BEGIN
FOR i IN c LOOP
FOR j IN 1..5
LOOP
EXECUTE IMMEDIATE 'SELECT ''NAME1'||to_Char(j)||''' from dual' INTO varValue;
dbms_output.put_line(j);
dbms_output.put_line(i.varValue);
END LOOP;
END LOOP;
END;
Actual issue is, I need to acccess the cell values of each row (i) given by cursor (c) like i.name11, i.name12....i.name1100. The logic to be deployed in each cell is same. So i need the column name used here i.e. name11 to be generated dynamically. That is alread done and stored to a variable varValue. Now how can i access the cells i.varValue such that var value is generated in the loop.
The error is as follows:
ORA-06550: line 14, column 34:
PLS-00302: component 'VARVALUE' must be declared
ORA-06550: line 14, column 11:
PL/SQL: Statement ignored
DECLARE
varValue VARCHAR(20);
CURSOR c IS
SELECT * FROM TEST1;
BEGIN
FOR i IN c LOOP
FOR j IN 1..5
LOOP
EXECUTE IMMEDIATE 'SELECT ''NAME1'||to_Char(j)||''' from dual' INTO varValue;
dbms_output.put_line(j);
dbms_output.put_line('NAME1'||to_Char(j)||' : '||varValue);
END LOOP;
END LOOP;
END;

Resources