Something is off but can't figure out what I am missing?
select
grade.sectionid,
grade.studentid,
course.courseid
FROM section
INNER JOIN grade
ON grade.sectionid = section.sectionid
INNER JOIN course
ON course.courseid = section.courseid;
DECLARE
CURSOR mycursor is
select
sectionid, studentid, courseid, coursename
FROM grade, course, section;
var_secID NUMBER(10);
var_studentID NUMBER (10);
var_gradeLetter CHAR(1);
var_coursetitle VARCHAR2(25);
BEGIN
OPEN mycursor;
LOOP
FETCH mycursor
INTO var_secID, var_studentID, var_gradeLetter, var_coursetitle;
EXIT WHEN mycursor%NOTFOUND;
If var_coursetitle(coursename,1) BETWEEN A AND F then
UPDATE grade
SET grade = 'A'
WHERE sectionid;
END IF;
END LOOP;
CLOSE mycursor;
END;
/
Keep getting this error:
ERROR at line 21:
ORA-06550: line 21, column 18:
PL/SQL: ORA-00920: invalid relational operator
ORA-06550: line 19, column 4:
PL/SQL: SQL Statement ignored
BETWEEN A AND F then
should perhaps be:
BETWEEN 'A' and 'F' then
You could do it without any PL/SQL, as:
update grade g set grade = 'A'
where g.sectionid in
( select s.sectionid from section s
join course c on c.courseid = s.courseid
where substr(c.coursename,-1, 1) between 'A' and 'F' );
However as a PL/SQL learning exercise, you could do it without any of the variable or cursor management:
begin
for r in (
select g.sectionid, g.studentid, c.courseid, c.coursename
, substr(c.coursename,-1, 1) as course_lastchar
from grade g
join section s on s.sectionid = g.sectionid
join course c on c.courseid = s.courseid
for update of grade
)
loop
if r.course_lastchar between 'A' and 'F' then
update grade set grade = 'A' where sectionid = r.sectionid;
end if;
end loop;
end;
(btw it's worth getting into the habit of laying code out neatly with a consistent indent size.)
Related
I am trying to create a form with dynamic region for purposes of printing. I have a simple PLSQL that works:
declare
cursor c_VYDEJKY is
select ID, INFO, CUSTOMER_ID
from VYDEJKY
where ID = :P54_NEW;
begin
sys.htp.p('<ul>');
for a in c_VYDEJKY loop
sys.htp.p('<li>' || a.ID || ' (' || a.CUSTOMER_ID || ')</li>' );
end loop;
sys.htp.p('</ul>');
end;
but when I try to join another table with LEFT JOIN or WHERE clause it doesnt work:
declare
cursor c_VYDEJKY is
select v.ID, v.INFO, v.CUSTOMER_ID, c.CUSTOMERNAME
from VYDEJKY v, CUSTOMERS c
where v.ID = :P54_NEW
AND v.CUSTOMER_ID > c.ID;
begin
sys.htp.p('<ul>');
for a in c_VYDEJKY loop
sys.htp.p('<li> ID VÝDEJKY :' || a.ID ||'</li>' );
sys.htp.p('<li> POZNÁMKY :' || a.INFO ||'</li>' );
sys.htp.p('<li> POZNÁMKY :' || c.CUSTOMERNAME ||'</li>' );
end loop;
sys.htp.p('</ul>');
end;
I am getting following error on c.CUSTOMERNAME
ORA-06550: line 15, column 39: PLS-00201: identifier 'C.CUSTOMERNAME' must be declared
Can someone please point to where I am makiing a mistake. I am really just starting with PLSQL.
Thank you,
JJ
Within the for loop, the prefix for the column names refers to the cursor row variable (for a in) not the table alias, so you need to specify:
a.CUSTOMERNAME
DECLARE
COUNTING1 NUMBER(1);
BEGIN
SELECT COUNT(VACATION_REMAINING_COUNT)
INTO COUNTING1
FROM VACATION
WHERE NAME = :P0_VNAME;
IF COUNTING1 > 0 THEN
SELECT VACATION_REMAINING_COUNT
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY CREATED DESC) ROW_ID,
V.VACATION_REMAINING_COUNT
FROM VACATION V
WHERE NAME = :P0_VNAME
)
WHERE ROW_ID = 1;
ELSE
SELECT USER_YEAR_VACATION FROM VA_USER WHERE NAME = :P0_VNAME;
END IF;
END;
ORA-06550: line 1, column 114: PLS-00103: Encountered the symbol "DECLARE" when expecting one of the following: ( - + case mod new not null continue avg count current exists max min prior sql stddev sum variance execute forall merge time timestamp interval date pipe
I wrote this sql code. but An error has occurred.
please help me..
You are missing the INTO clause for your second and third SELECT statements.
However, I would skip using the first COUNT statement and just try to find the latest row and catch a NO_DATA_FOUND exception if it occurs:
DECLARE
p_vacation_remaining VACATION.VACATION_REMAINING_COUNT%TYPE;
BEGIN
BEGIN
SELECT vacation_count_remaining
INTO p_vacation_remaining
FROM vacation
WHERE name = :P0_VNAME
ORDER BY created DESC
FETCH FIRST 1 ROW ONLY;
EXCEPTION
WHEN NO_DATA_FOUND THEN
SELECT USER_YEAR_VACATION
INTO p_vacation_remaining
FROM VA_USER
WHERE NAME = :P0_VNAME;
END;
-- Do something with p_vacation_remaining
DBMS_OUTPUT.PUT_LINE( p_vacation_remaining );
END;
/
I have some code that won't run because it expects an INTO clause in the select statement:
DECLARE
StatusCode VARCHAR2(255);
BEGIN
StatusCode := '';
SELECT acc.AccountNo,
acc.AccountTitle,
NVL(cus.Title,'') AS Title,
NVL(cus.Surname,'') AS Surname,
NVL(cus.Forename1,'') AS Forename1,
acc.GBP_Balance,
CASE
WHEN sc.ExcludeFromSCV = 1
THEN 'Yes'
ELSE 'No'
END AS ExcludedAccount
FROM DIM_FM_FSCS_Account acc
INNER JOIN DIM_FM_FSCS_CustomerAccLink lnk
ON acc.ID = lnk.FSCSAccountLink
LEFT JOIN DIM_FM_FSCS_Customer cus
ON lnk.FSCSCustomerLink = cus.ID
LEFT JOIN DIM_FM_FSCS_StatusCode sc
ON (acc.ExclusionCode = ''
AND sc.Code = acc.AccountStatusCode)
OR (sc.Code = acc.ExclusionCode)
WHERE (acc.AccountStatusCode = StatusCode
AND acc.ExclusionCode = '')
OR acc.ExclusionCode = StatusCode;
END;
However I am unsure how to add this and how it'll work with this script.
Can I have some help?
The error message is clear enough: in PL/SQL you can not make a SELECT query without fetching the result into some variable.
For example:
SQL> begin
2 select 1, 2 from dual;
3 end;
4 /
select 1, 2 from dual;
*
ERROR at line 2:
ORA-06550: riga 2, colonna 5:
PLS-00428: an INTO clause is expected in this SELECT statement
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 select 1, 2
6 into v1, v2
7 from dual;
8 end;
9 /
PL/SQL procedure successfully completed.
SQL>
So you need to define variable to handle the result(s) of your query.
Notice that in the example I used two scalar variables, but if your query can return more than one row, you will need to use some collection to fetch your data; for example:
declare
type tyListNum is table of number;
vList1 tyListNum;
vList2 tyListNum;
begin
select 1, 2
bulk collect into vList1, vList2
from dual
connect by level <= 2;
--
-- whatever you need to do with the fetched values
end;
I have the following piece of code which is returning PLS-00222. So I want to compare the dates of an "old" id with a "new" id retrieved from cur_c1.
Here is the cursor where cur_table records come from:
CURSOR table_cur IS
SELECT
NEW_ID,
OLD_ID
FROM
TABLE_C
WHERE
C_ID = in_parameter_id; --This is input for the procedure
CURSOR cur_c1 (c_in_id NUMBER) IS
SELECT
FIELD_DATE
FROM
TABLE_D
WHERE
FIELD_ID = c_in_id;
FOR cur_table IN table_cur LOOP
...stuff...;
FOR c_cur IN cur_c1(cur_table.NEW_ID) LOOP
IF c_cur.field_date > cur_c1(cur_table.OLD_ID).field_date
THEN
v_exist := 'Y';
END IF;
END LOOP;
END LOOP;
How can I achieve my desired result?
Error:
2593/56 PLS-00222: no function with name 'cur_c1' exists in this scope
2593/17 PL/SQL: Statement ignored
I suggest that using cursors here is inefficient. Instead I suggest the following:
FOR cur_table IN table_cur LOOP
...stuff...;
SELECT d_old.FIELD_DATE,
d_new.FIELD_DATE
INTO dtOld_field_date,
dtNew_field_date
FROM DUAL
LEFT OUTER JOIN TABLE_D d_old
ON d_old.FIELD_ID = cur_table.OLD_ID
LEFT OUTER JOIN TABLE_D d_new
ON d_new.FIELD_ID = cur_table.NEW_ID;
IF dtNew_field_date > dtOld_field_date THEN
v_exist := 'Y';
END IF;
END LOOP;
Best of luck.
I'm currently working on creating a stored procedure in PL SQL that will turn a data type number 4 to the varchar2 to A.
SELECT s.sname, g.sid, s.sid, c.cid, g.cid,
CAST(CASE g.grade
WHEN 4 THEN 'A'
WHEN 3 THEN 'B'
WHEN 2 THEN 'C'
WHEN 1 THEN 'D'
WHEN 0 THEN 'F'
ELSE 'No Value'
END AS varchar2(55)) AS Grades
FROM student s, grades g, class c
WHERE c.cid = g.cid
AND g.sid = s.sid
AND g.sid = s.sid;
This is works as is but once I add in this in a create procedure it errors out as Unexpected error
Error code -6502: ORA-06502: PL/SQL: numeric or value error:character to number conversion error.
Also, I have tried adding the below within the procedure and return the same error.
EXIT WHEN c1%NOTFOUND; -- exit check
dbms_output.put_line('Student Name: '|| s_sname);
dbms_output.put_line('Class Name: ' || c_cname);
dbms_output.put_line('Grade: ' || to_char(g_grade, 'ABCDF');
dbms_output.put_line('-----------------');
In the above I'm trying to print the letter grade and not the numerical grade.
You need to paste the entire code. It works for me.
create table testing(i int);
insert into testing values (0);
insert into testing values (1);
insert into testing values (2);
insert into testing values (3);
create or replace procedure p
is
begin
for i in (select CAST(CASE g.grade
WHEN 4 THEN 'A'
WHEN 3 THEN 'B'
WHEN 2 THEN 'C'
WHEN 1 THEN 'D'
WHEN 0 THEN 'F'
ELSE 'No Value'
END AS varchar2(55)) AS Grades
from testing
)
loop
dbms_output.put_line(i.Grades);
end loop;
end;
/
set serveroutput on;
begin
p;
end;
/
D
C
F
B
PL/SQL procedure successfully completed.