For loop using VARCHAR2 - sql

I'm trying to display the info for each student using this code
DECLARE
CURSOR cursor1 IS SELECT STUDENTNAME, COURSEID, COURSEDESCRIPTION, COURSECREDITS, GRADE
FROM STUDENTINFO;
S_NAME STUDENTINFO.STUDENTNAME%TYPE;
S_COURSEID STUDENTINFO.COURSEID%TYPE;
S_COURSEDESCRIPTION STUDENTINFO.COURSEDESCRIPTION%TYPE;
S_COURSECREDITS STUDENTINFO.COURSECREDITS%TYPE;
S_GRADE STUDENTINFO.GRADE%TYPE;
BEGIN
OPEN CURSOR1;
LOOP
FETCH CURSOR1 INTO S_NAME, S_COURSEID, S_COURSEDESCRIPTION, S_COURSECREDITS, S_GRADE;
EXIT WHEN cursor1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Student Name: ' || S_NAME);
DBMS_OUTPUT.PUT_LINE(S_COURSEID || S_COURSEDESCRIPTION || S_COURSECREDITS || S_GRADE);
DBMS_OUTPUT.PUT_LINE(CHR(10));
END LOOP;
CLOSE CURSOR1;
END;
/
My output should be similar to
Student Name: John
CMIS 101 Intro to Info. Systems 3 B
CMIS 301 System Analysis 3 C
CMIS 451 Client/Server Systems 3 C
I'm pretty sure I should be using a for loop which I created
DECLARE
CURSOR cursor2 IS SELECT STUDENTNAME, COURSEID, COURSEDESCRIPTION, COURSECREDITS, GRADE
FROM STUDENTINFO;
search_student STUDENTINFO.STUDENTNAME%TYPE;
BEGIN
FOR v_Record IN cursor2
LOOP
IF v_Record.STUDENTNAME = &SEARCH_STUDENT THEN
DBMS_OUTPUT.PUT_LINE('Student Name: ' || STUDENTNAME);
DBMS_OUTPUT.PUT_LINE(COURSEID || COURSEDESCRIPTION || COURSECREDITS || GRADE);
DBMS_OUTPUT.PUT_LINE(CHR(10));
END IF;
END LOOP;
END;
/
However, when I type in a name for search_student, I'm just given the error
Identifier "insertnamehere"
Can I not use VARCHAR2 when searching? Is it only usable with numbers?

There are a few issues with your code.
For a start, why use PL/SQL to do this? You should just use a SQL statement directly. I'm going to assume that this is a homework question though (*sigh* - surely there are better examples to use?!).
1. IF v_Record.STUDENTNAME = &SEARCH_STUDENT - when you pass in a value for search_student, the client replaces the term &search_student. So, either you must ensure that the single quotes to specify the studentname is a string when you define the search_student (ie. when prompted for search_student you enter "'SomeName'") OR put the single quotes around the &SEARCH_STUDENT - ie. IF v_Record.STUDENTNAME = '&SEARCH_STUDENT'
2. When referencing the fields returned by the cursor in the for loop, you need to reference the record that the values were fetched into. Therefore DBMS_OUTPUT.PUT_LINE('Student Name: ' || STUDENTNAME); should be DBMS_OUTPUT.PUT_LINE('Student Name: ' || v_Record.STUDENTNAME);
3. Finally, if you're looking to output a single student record at a time, put the filter in the cursor, not in the loop.

Related

PL/SQL: Cursor doubles the last record from the table

I created the following PL/SQL anonymous block. The cursor below retrieves data from the select statement:
select mod_benutzer, count(*)
from dok_auspraegung
where parent_objekt_id = 1093
group by mod_benutzer;
This statement displays exactly two records:
DDMS_USER | 8
HU2MAMU | 14
But when I want to display these two records by cursor, it displays "HU2MAMU|14" two times like below:
Modifications:
DDMS_USER, 8x
HU2MAMU, 14x
HU2MAMU, 14x
declare
my_exception_1 exception;
var_parent_objekt_id dok_auspraegung.parent_objekt_id%TYPE := 1093;
var_date varchar(30);
var_mod_benutzer varchar2(10);
var_benutzer_modifs number;
cursor cursor_dok_auspraegung
is select mod_benutzer, count(*) from dok_auspraegung
where parent_objekt_id = 10935797565
group by mod_benutzer;
begin
select distinct to_char(mod_datum,'YYYY-MON-DD') into var_date from dok_auspraegung where parent_objekt_id = var_parent_objekt_id;
IF var_date is not null THEN
dbms_output.put_line('Parent Object ID' || ': ' || var_parent_objekt_id);
dbms_output.put_line('Date: ' || ' ' || var_date);
ELSE RAISE my_exception_1;
END IF;
open cursor_dok_auspraegung;
dbms_output.put_line('Modifications:');
loop
fetch cursor_dok_auspraegung into var_mod_benutzer, var_benutzer_modifs;
dbms_output.put(var_mod_benutzer);
dbms_output.put_line(', ' || var_benutzer_modifs || 'x');
exit when cursor_dok_auspraegung%notfound;
end loop;
dbms_output.put_line(cursor_dok_auspraegung%rowcount);
close cursor_dok_auspraegung;
exception
when NO_DATA_FOUND then
dbms_output.put_line('Parent Object ID not found!');
when my_exception_1 then
dbms_output.put_line('');
end;
What is the reason of that?
Because exiting from the cursor occurs after printing the value of the variables in the current case, this repeats the last value to be printed. So, it should occur before printing as follows
loop
fetch cursor_dok_auspraegung into var_mod_benutzer, var_benutzer_modifs;
exit when cursor_dok_auspraegung%notfound;
dbms_output.put(var_mod_benutzer);
dbms_output.put_line(', ' || var_benutzer_modifs || 'x');
end loop;

Using multiple procedures and multiple cursors in a package

I have created a package with two procedures and two cursors in it, but while executing the procedure, it is executed successful, but same record executed multiple times and a buffer overflow occurred.
I also tried removing the loop from the cursor but for 1 record that will be fine and for multiple record it won't work as expected.
EXPECTED
I just need to remove multiple execution of same record from the procedure where i am getting multiple execution of same record
for single procedure and single cursor it is working properly but for multiple cursor and multiple procedure i am getting problem here which caused buffer overflow too where i need different record
Is there any alternative way that I can fix the problem ?
CREATE OR REPLACE PACKAGE test.report AS
PROCEDURE distribution (
code_in IN user.test.code%TYPE,
fromdate date,
todate date
);
PROCEDURE tdvalue (
id IN user.test.custid%TYPE
);
END report;
/
Package Body
CREATE OR REPLACE PACKAGE BODY test.report as
----------VARIABLE DECLARATION----------------
code_in user.test.code%TYPE;
custidin user.test.custid%TYPE;
fromdate DATE;
todate DATE;
diff number(17,2);
---------------CURSOR DECLARATION--------------
CURSOR td_data(code_in user.test.code%TYPE,
fromdate date,
todate date
) IS
( SELECT
test.code,
COUNT(test.code) AS count,
SUM(test2.Deposit_amount) AS total,
test.currency
FROM
user.test2
JOIN user.test ON test2.acid = test.acid
WHERE
user.test2.open_effective_date BETWEEN TO_DATE(fromdate, 'dd-mm-yyyy') AND TO_DATE(todate, 'dd-mm-yyyy')
and
user.test.code = code_in
GROUP BY
test.code,test.currency
);
td__data td_data%rowtype;
CURSOR C_DATA(custidin user.test.custid%TYPE) IS SELECT
test.custid,
test2.id,
TO_DATE(test2.initial_date, 'dd-mm-yyyy') - TO_DATE(test2.end_date, 'dd-mm-yyyy') AS noofdays,
round(((test2.deposit_amount *((TO_DATE(test2.initial_date, 'dd-mm-yyyy') - TO_DATE(test2.end_date, 'dd-mm-yyyy'
)) / 365) * test4.interest_rate) / 100), 2) + test2.deposit_amount AS calculated_amount,
SUM(test.flow_amt) + test2.deposit_amount AS system_amount
FROM
user.test
JOIN user.test2 ON test3.entity_id = test2.id
WHERE
test.custid = custidin
GROUP BY
test.custid,
test2.id;
c__data c_data%ROWTYPE;
PROCEDURE distribution
(
code_in IN user.test.code%TYPE,
fromdate in date,
todate in date
)
AS
BEGIN
OPEN td_data(code_in,fromdate,todate);
loop
FETCH td_data INTO td__data;
dbms_output.put_line(td__data.code
|| ' '
|| td__data.count
|| ' '
||td__data.currency
||' '
||td__data.total
);
end loop;
CLOSE td_data;
END distribution;
PROCEDURE tdvalue (
custidin IN user.test.custid%TYPE
)
AS
BEGIN
open c_data(custidin);
fetch c_data into c__data;
loop
diff:= c__data.calculated_amount- c__data.system_amount;
dbms_output.put_line(c__data.custid
|| ' '
|| c__data.noofdays
|| ' '
|| c__data.end_date
|| ' '
|| c__data.initial_date
|| ' '
|| c__data.calculated_amount
||' '
||diff
);
end loop;
close c_data;
END tdvalue;
END report;
/
To run
ALTER SESSION set nls_date_format='dd-mm-yyyy';
SET SERVEROUTPUT ON;
EXEC REPORT.DISTRIBUTION('872328','01-02-2016','08-02-2019');
/
EXEC REPORT.tdvalue('S9292879383SS53');
Buffer overflow - ORU-10027 - happens when the total number of bytes displayed through DBMS_OUTPUT exceeds the size of the serveroutput buffer. The default is only 20000 bytes (who knows why?). Your session is using that default because of how you enable serveroutput. Clearly one record is less than 2000 and you only hit that limit when you run for multiple records.
To fix this try this
SET SERVEROUTPUT ON size unlimited
It's not actually unlimited, but the upper bound is the PGA limit (session memory) and you really shouldn't hit that limit with DBMS_OUTPUT. Apart from anything else who would read all that?
So the other problem with your code - as #piezol points out - is that your loops have no exit points. You should test whether the FETCH actually fetched anything and exit if it didn't:
loop
FETCH td_data INTO td__data;
exit when td_data%notfound;
dbms_output.put_line(td__data.code
|| ' '
|| td__data.count
|| ' '
||td__data.currency
||' '
||td__data.total
);
end loop;
Remembering to do this is just one reason why implicit cursors and cursor for loops are preferred over explicit cursors.
The second cursor loop is even worse because not only does it not have an exist point, the fetch is outside the loop. That's why you have repeated output for the same record.
So let's rewrite this ...
open c_data(custidin);
fetch c_data into c__data; -- should be inside
loop
diff:= c__data.calculated_amount- c__data.system_amount;
… as a cursor for loop:
PROCEDURE tdvalue (
custidin IN user.test.custid%TYPE
)
AS
BEGIN
for c__data in c_data(custidin)
loop
diff:= c__data.calculated_amount- c__data.system_amount;
dbms_output.put_line(c__data.custid
|| ' '
|| c__data.noofdays
|| ' '
|| c__data.end_date
|| ' '
|| c__data.initial_date
|| ' '
|| c__data.calculated_amount
||' '
||diff
);
end loop;
END tdvalue;
No need for OPEN, CLOSE or FETCH, and no need to check when the cursor is exhausted.
In PL/SQL, the preferred mechanism for setting the DBMS_OUTPUT buffer size would be within your procedure. This has the benefit of working in any client tool, such as Java or Toad (though it is still up to the client tool to retrieve the output from DBMS_OUTPUT).
DBMS_Output.ENABLE
Pass in a parameter of NULL for unlimited buffer size.
It would go like this:
BEGIN
DBMS_OUTPUT.ENABLE(NULL);
FOR I IN 1..1000 LOOP
DBMS_OUTPUT.PUT_LINE('The quick red fox jumps over the lazy brown dog.');
END LOOP;
END;
/
Bonus fact:
You can use the other functions and procedures in DBMS_OUTPUT to roll your own if you aren't using SQL*Plus or a DBMS_OUTPUT-savvy tool like Toad.
You can use the GET_LINE or GET_LINES procedures from your client code to get whatever may have been written to DBMS_OUTPUT.
GET_LINE

Looking at IF, WHERE, and WHEN in PL SQL

I am completing an academic assignment that asks to prompt the user for their target sales and their employee id. If the target sales exceeds or equates to that of the actual company sales for 2015, then raises can be applied.
I've composed a majority of code but I am stuck on the END IF; statements on line 25. I'm receiving error(s)
ORA-06550, PLS-00103: Encountered the symbol "WHERE" when expecting
one of the following.
I think I might be struggling to integrate the if statement that compares the user input to the company sales for 2015.
Insights greatly appreciated! Thank you!
accept emp_target prompt 'Please enter your company sales target: '
accept empno prompt 'Please enter your employee ID: '
DECLARE
emp_target NUMBER := &emp_target;
cmp_target NUMBER;
empno emp_employees.emp_id%type := &empno;
new_sal emp_employees.salary%type;
cnt number;
CURSOR sales_cur IS
SELECT SUM(oe_orderDetails.quoted_price)
FROM oe_orderDetails
JOIN oe_orderHeaders
ON oe_orderDetails.order_id = oe_orderHeaders.order_id
WHERE oe_orderHeaders.order_date >= to_date('1.1.' || 2015, 'DD.MM.YYYY')
and oe_orderHeaders.order_date < to_date('1.1.' || (2015 + 1), 'DD.MM.YYYY');
BEGIN
OPEN sales_cur;
FETCH sales_cur INTO cmp_target;
IF cmp_target >= emp_target THEN
UPDATE emp_employees SET
emp_employees.salary = case WHEN emp_employees.dept_id = 10 THEN emp_employees.salary * 1.1
WHEN emp_employees.emp_id = 145 THEN emp_employees.salary * 1.15
WHEN emp_employees.dept_id = 80 THEN emp_employees.salary * 1.2
ELSE emp_employees.salary
END IF;
END
WHERE emp_employees.emp_id = empno
returning emp_employees.salary into new_sal;
cnt := sql%rowcount;
IF cnt > 0 THEN
dbms_output.put_line('Employee ' || empno || ', new salary = ' || new_sal);
ELSE
dbms_output.put_line('Nobody got new salary');
END IF;
END;
/
The main issue is that you have misplaced the CASE block's end and where clause out after END IF.
Apart from that I would say that the cursor block was not required to store a simple SUM, but i'll let you use it since you are learning for an assignment.
The other problem after you fix the first one is your returning emp_employees.salary into new_sal. A scalar variable can't contain multiple rows returned from the dml which updates more than one row. You should use a collection(nested table) instead. Use RETURNING BULK COLLECT INTO to load it and loop over later to display your final message.
Please read all my code comments carefully. I cannot test the whole code for any errors as I have none of your tables. You should fix if there are any if you can or let us know if you can't.
ACCEPT emp_target PROMPT 'Please enter your company sales target: '
ACCEPT empno PROMPT 'Please enter your employee ID: '
DECLARE
emp_target NUMBER := &emp_target;
cmp_target NUMBER;
empno emp_employees.emp_id%TYPE := &empno;
TYPE sal_type IS
TABLE OF emp_employees.salary%TYPE; --nested table(collection) of salary
new_sal sal_type; -- a collection variable
cnt NUMBER;
CURSOR sales_cur IS SELECT SUM(oe_orderdetails.quoted_price)
FROM oe_orderdetails
JOIN oe_orderheaders ON oe_orderdetails.order_id = oe_orderheaders.order_id
WHERE oe_orderheaders.order_date >= TO_DATE('1.1.' || 2015,'DD.MM.YYYY') AND
oe_orderheaders.order_date < TO_DATE('1.1.' || (2015 + 1),'DD.MM.YYYY'); --is it required to specify (2015 + 1) instead of 2016?
BEGIN
OPEN sales_cur;
FETCH sales_cur INTO cmp_target;
IF
cmp_target >= emp_target
THEN
UPDATE emp_employees
SET
emp_employees.salary =
CASE
WHEN emp_employees.dept_id = 10 THEN emp_employees.salary * 1.1
WHEN emp_employees.emp_id = 145 THEN emp_employees.salary * 1.15
WHEN emp_employees.dept_id = 80 THEN emp_employees.salary * 1.2
ELSE emp_employees.salary
END
WHERE emp_employees.emp_id = empno --misplaced where and end
RETURNING emp_employees.salary BULK COLLECT INTO new_sal;
END IF;
cnt := new_sal.count; --no of records in nested table
IF
cnt > 0
THEN
FOR i IN new_sal.first..new_sal.last LOOP
dbms_output.put_line('Employee ' || empno || ', new salary = ' || new_sal(i) );
END LOOP;
ELSE
dbms_output.put_line('Nobody got new salary');
END IF;
CLOSE sales_cur; -- always remember to close the cursor
END;
/

PLS-00394: Wrong number of values in the INTO list of a fetch statement

This is my attempt in creating a cursor in a stored procedure
--Second Stored Procedure--
CREATE OR REPLACE PROCEDURE sp_GetDiscountedRate (DiscountCode IN
VARCHAR2,Percentage IN NUMBER, ReserveDate IN DATE)
IS --Code declaration section--
--variables to store column values returned from select into
pPassengerID VARCHAR2(10);
pFirst VARCHAR2(20);
pMiddle VARCHAR2(20);
pLast VARCHAR2(20);
pPassengerType CHAR (1);
uUSMilitaryID VARCHAR (8);
uMilitaryBranch VARCHAR2 (20);
uMilitaryDiscountCode VARCHAR2(8);
rFlightNumber VARCHAR2(6);
rReservationCost NUMBER(6);
rReservationDate DATE;
--Declare Cursor
CURSOR cur_USMilitary IS
--Query cursor will point to results
SELECT P.PassengerID, P.First, P.Middle, P.Last, P.PassengerType,
U.USMilitaryID, U.MilitaryBranch,
U.MilitaryDiscountCode, R.FlightNumber, R.ReservationCost,
R.ReservationDate,
CASE U.MilitaryDiscountCode WHEN DiscountCode THEN
Percentage*R.ReservationCost
ELSE R.ReservationCost END "REVISED_RESERVATION_COST"
FROM PASSENGER P, US_Military U, RESERVATION R
WHERE P.PassengerID = U.MPassengerID
AND P.PassengerID = R.PassengerID
AND U.MilitaryDiscountCode = DiscountCode
AND R.ReservationDate = ReserveDate;
--Start Execution section--
BEGIN
--Open Cursor
OPEN cur_USMilitary; -- open cursor for use
--loop to display each record returned by cursor
--Use PL/SQL language control or loop to display each record pointed by cursor
LOOP
--Fetch cursor data
FETCH cur_USMilitary INTO pPassengerID,
pFirst,pMiddle,pLast,pPassengerType,
uUSMilitaryID,uMilitaryBranch,uMilitaryDiscountCode,rFlightNumber,
rReservationCost,rReservationDate;
EXIT WHEN cur_USMilitary%NOTFOUND;
--Display each record
--Displaying the results
DBMS_OUTPUT.PUT_LINE ('CUSTOMER INFORMATION: ');
DBMS_OUTPUT.PUT_LINE ('The PassengerID is: ' ||pPassengerID);
DBMS_OUTPUT.PUT_LINE ('First Name of passenger is: ' ||pFirst);
DBMS_OUTPUT.PUT_LINE ('Middle Name of passenger is: ' ||pMiddle);
DBMS_OUTPUT.PUT_LINE ('Last Name of passenger is: ' ||pLast);
DBMS_OUTPUT.PUT_LINE ('Passenger Type of customer is: ' ||pPassengerType);
DBMS_OUTPUT.PUT_LINE ('US Military ID of Passenger is: ' ||uUSMilitaryID);
DBMS_OUTPUT.PUT_LINE ('Military Branch of passenger is: ' ||uMilitaryBranch);
DBMS_OUTPUT.PUT_LINE ('Military Discount code of passenger is: ' ||uMilitaryDiscountCode);
DBMS_OUTPUT.PUT_LINE ('Flight number of passenger is: ' ||rFlightNumber);
DBMS_OUTPUT.PUT_LINE ('Reservation Cost of passenger is: ' ||rReservationCost);
DBMS_OUTPUT.PUT_LINE ('Reservation Date of passenger is: ' ||rReservationDate);
END LOOP;
CLOSE cur_USMilitary; --close cursor
END sp_GetDiscountedRate;
I get this error:
Error(36,9): PL/SQL: SQL Statement ignored
Error(36,9): PLS-00394: wrong number of values in the INTO list of a FETCH statement
I fully understand the error. I checked the number of columns and it looks like to me that they match the number of columns within the query. I've also checked the datatypes to make sure it was correct.
You have
12 columns in your cursor's SELECT part
but
11 columns in FETCH statement part
, i observe
CASE U.MilitaryDiscountCode WHEN DiscountCode THEN
Percentage*R.ReservationCost
ELSE R.ReservationCost END "REVISED_RESERVATION_COST"
part is missing in FETCH( or should be omitted in the SELECT part ).
It also represents a column, and it spoils 1-1 correspondence, which yields that error.
This is what happens when you overcomplicate things, I'm afraid. I don't see any need for all those variables and the corresponding fetch into that is hard to keep in sync. Why not just:
create or replace procedure sp_getdiscountedrate
( discountcode in varchar2
, percentage in number
, reservedate in date )
is
begin
for r in (
select p.passengerid
, p.first
, p.middle
, p.last
, p.passengertype
, u.usmilitaryid
, u.militarybranch
, u.militarydiscountcode
, r.flightnumber
, r.reservationcost
, r.reservationdate
, case u.militarydiscountcode
when discountcode then percentage * r.reservationcost
else r.reservationcost
end as revised_reservation_cost
from passenger p
join us_military u
on u.mpassengerid = p.passengerid
join reservation r
on r.passengerid = p.passengerid
and r.discountcode = u.militarydiscountcode
and r.reservedate = r.reservationdate
)
loop
dbms_output.put_line('CUSTOMER INFORMATION:');
dbms_output.put_line('The PassengerID is: ' || r.passengerid);
dbms_output.put_line('First Name of passenger is: ' || r.first);
dbms_output.put_line('Middle Name of passenger is: ' || r.middle);
dbms_output.put_line('Last Name of passenger is: ' || r.last);
dbms_output.put_line('Passenger Type of customer is: ' || r.passengertype);
dbms_output.put_line('US Military ID of Passenger is: ' || r.usmilitaryid);
dbms_output.put_line('Military Branch of passenger is: ' || r.militarybranch);
dbms_output.put_line('Military Discount code of passenger is: ' || r.militarydiscountcode);
dbms_output.put_line('Flight number of passenger is: ' || r.flightnumber);
dbms_output.put_line('Reservation Cost of passenger is: ' || r.reservationcost);
dbms_output.put_line('Reservation Date of passenger is: ' || r.reservationdate);
dbms_output.put_line('Revised reservation cost is: ' || r.revised_reservation_cost);
end loop;
end sp_getdiscountedrate;
(Untested)
You go through all the trouble of calculating "REVISED_RESERVATION_COST", and then you don't read it from the cursor.
No wonder Oracle is complaining. You need a variable for this column as well.
I would also advise you to learn to use modern, proper, explicit JOIN syntax.

Simple PL/SQL Code will not run. I cannot find the error

I've been tweaking and trying to debug this PL/SQL code for like 4 hours now. I have also tried to search on here but it is so specific that I really need help. Here is my code, When I try to run it, the two prompt questions pop up. After I answer the second one, oracle just stops running.
---- File PLh20.sql
-- Author: <<< NAME >>>
-------------------------------------------------------------------
SET SERVEROUTPUT ON
SET VERIFY OFF
------------------------------------
ACCEPT rateDecrement NUMBER PROMPT 'Enter the rate decrement: '
ACCEPT allowedMinRate NUMBER PROMPT 'Enter the allowed min. rate: '
DECLARE
sr boats%ROWTYPE;
CURSOR sCursor IS
SELECT B.bid, B.bname, B.color, B.rate, B.length, B.logKeeper
FROM Boats B
WHERE B.bid NOT IN (SELECT bid FROM Reservations);
BEGIN
OPEN sCursor;
LOOP
-- Fetch the qualifying rows one by one
FETCH sCursor INTO sr;
EXIT WHEN sCursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('+++++ old rate: '||sr.rate||' '
||sr.rate||);
sr.rate := sr.rate - &rateDecrement;
-- A nested block
DECLARE
belowAllowedMin EXCEPTION;
BEGIN
IF sr.rate < &allowedMinRate
THEN RAISE belowAllowedMin;
ELSE UPDATE Boats
SET rate = sr.rate
WHERE Boats.bid = sr.bid;
-- Print the boat new record
DBMS_OUTPUT.PUT_LINE ('+++++ new row: '||sr.bid||' '
||sr.rate||);
END IF;
EXCEPTION
WHEN belowAllowedMin THEN
DBMS_OUTPUT.PUT_LINE('+++++ Update rejected: '||
'The new rate would have been: '|| sr.rate);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('+++++ update rejected: ' ||
SQLCODE||'...'||SQLERRM);
END;
-- end of the nested block
END LOOP;
COMMIT;
CLOSE sCursor;
END;
SELECT S.sid, S.rating
FROM sailors S, reservations R, boats B
WHERE S.sid = R.sid AND
R.bid = B.bid;
UNDEFINE rateDecrement
UNDEFINE allowedMinRate
DBMS_OUTPUT.PUT_LINE ('+++++ new row: '||sr.bid||' '||sr.rate||);
DBMS_OUTPUT.PUT_LINE ('+++++ old rate: '||sr.rate||' '||sr.rate||);
Looks like these 2 are the problem. There should not be '||' at the end.