how can i resolve this pl/sql declare error? - oracle

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;
/

Related

Oracle PLS 00103 error for procedure while executing it

I have below procedure giving me error as
Error(17,3): PLS-00103: Encountered the symbol "FOR" when expecting one of the following: ( - + case mod new not null select with continue avg count current exists max min prior sql stddev sum variance execute fora
Here is the procedure.
PROCEDURE DeactiveUsers (
P_DeactiveUsers_OUT OUT SYS_REFCURSOR ) AS
BEGIN
OPEN P_DeactiveUsers_OUT FOR
for P_DeactiveUsers_Lst in(
select * from (
select username, MAX(TRANSACTION_DATE) As last_login_date
from r4g_application_activity_log
Group By username
) where last_login_date <= sysdate-90
order by 2 desc
)
update r4g_application_activity_log
set ISACTIVE = 1
where USERNAME = P_DeactiveUsers_OUT.username;
EXCEPTION
WHEN no_data_found THEN
INS_UMS_ERRORLOG(SQLCODE||' : '||SUBSTR(SQLERRM, 1, 200),null,'DeactiveUsers',null,null,null,'DB : DeactiveUsers','Scheduler - UMS_DeactiveUser');
WHEN others THEN
INS_UMS_ERRORLOG(SQLCODE||' : '||SUBSTR(SQLERRM, 1, 200),null,'DeactiveUsers',null,null,null,'DB : DeactiveUsers','Scheduler - UMS_DeactiveUser');
END DeactiveUsers;
Hm, yes - procedure is here, but - what is its purpose? The way you put it, it seems that it shouldn't return anything so you don't really want to open a ref cursor, but use a cursor FOR loop which then updates the log table.
If that's so,
remove OUT parameter
remove OPEN clause (btw. you've got two FORs)
use FOR loop
remove WHEN NO_DATA_FOUND as there's nothing that could raise it
PROCEDURE DeactiveUsers -- (P_DeactiveUsers_OUT OUT SYS_REFCURSOR)
AS
BEGIN
--OPEN P_DeactiveUsers_OUT FOR
FOR P_DeactiveUsers_Lst
IN ( SELECT *
FROM ( SELECT username, MAX (TRANSACTION_DATE) AS last_login_date
FROM r4g_application_activity_log
GROUP BY username)
WHERE last_login_date <= SYSDATE - 90
ORDER BY 2 DESC)
LOOP
UPDATE r4g_application_activity_log
SET ISACTIVE = 1
WHERE USERNAME = P_DeactiveUsers_OUT.username;
END LOOP;
EXCEPTION
-- WHEN no_data_found THEN
-- INS_UMS_ERRORLOG(SQLCODE||' : '||SUBSTR(SQLERRM, 1, 200),null,'DeactiveUsers',null,null,null,'DB : DeactiveUsers','Scheduler - UMS_DeactiveUser');
WHEN OTHERS
THEN
INS_UMS_ERRORLOG (SQLCODE || ' : ' || SUBSTR (SQLERRM, 1, 200),
NULL,
'DeactiveUsers',
NULL,
NULL,
NULL,
'DB : DeactiveUsers',
'Scheduler - UMS_DeactiveUser');
END DeactiveUsers;
[EDIT]
As you want to return list of deactivated users, then you could do it as follows: instead of a ref cursor, just loop through result set, do the update and return a collection of deactivated users:
PROCEDURE deactiveusers (p_deactivataed OUT SYS.odcivarchar2list)
IS
l_deactivated SYS.odcivarchar2list := sys.odcivarchar2list ();
BEGIN
FOR cur_r
IN ( SELECT *
FROM ( SELECT username, MAX (TRANSACTION_DATE) AS last_login_date
FROM r4g_application_activity_log
GROUP BY username)
WHERE last_login_date <= SYSDATE - 90
ORDER BY 2 DESC)
LOOP
UPDATE r4g_application_activity_log
SET isactive = 1
WHERE username = cur_r.username;
l_deactivated.EXTEND;
l_deactivated (l_deactivated.LAST) := cur_r.username;
END LOOP;
p_deactivated := l_deactivated;
END;
You'd call it as e.g.
DECLARE
l_deactivated SYS.odcivarchar2list;
BEGIN
deactiveusers (l_deactivated);
FOR i IN l_deactivated.FIRST .. l_deactivated.LAST
LOOP
DBMS_OUTPUT.put_line (l_deactivated (i));
END LOOP;
END;
/

I am getting an error message in Oracle SQL stored procedure

I am trying the following code
CREATE OR REPLACE PROCEDURE sal2
AS
BEGIN
SELECT sal
FROM emp
END
And I'm getting this error
Error at line 7: PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
( begin case declare end exception exit for goto if loop mod
null pragma raise return select update while with
<< continue close current delete fetch lock
insert open rollback savepoint set sql execute commit forall
merge pipe purge
5. from emp
6. return 1
7. END
What I want to do is to get a sal column from emp table.
There are multiple issues with code as following;
create or replace procedure sal2
AS
Lv_var number; -- added variable for holding select value
BEGIN
select sal
Into lv_var -- into is needed in select
from emp; -- you missed this semicolon
-- you must use where clause as into variable can hold single value
-- so you must restrict this query to return only 1 record.
END; -- you missed this semicolon
/
Cheers!!
First you have to put the semicolon at the end of each line and after the END keyword. Then the SELECT statement is also wrong you have to load the result in a variable.
Here is the solution for multiple rows.
CREATE OR REPLACE PROCEDURE sal2
AS
CURSOR c_salaries IS SELECT salary FROM employees;
TYPE t_salaries IS TABLE OF c_salaries%rowtype INDEX BY BINARY_INTEGER;
v_salaries t_salaries;
BEGIN
OPEN c_salaries;
FETCH c_salaries BULK COLLECT INTO v_salaries;
CLOSE c_salaries;
END;
And one for a single row result.
CREATE OR REPLACE PROCEDURE sal2
AS
v_salary employees.salary%rowtype;
BEGIN
SELECT salary INTO v_salary
FROM employees WHERE employee_id = 100;
END;

Trying to assign a single value from a query to a variable... what am i doing wrong?

I am trying to to set a variable (v_flag_id) to the result of a query. I've been looking online at examples and it seems like my formatting/syntax is correct. What am i doing wrong? Thanks in advance.
create or replace PROCEDURE RUN_AGG
is
declare
v_Flag_id Number := select flag_id from flag where flag_tx = 'Processed / Calculated';
CURSOR hours IS
SELECT distinct(HR) as RHR
, submission_value_id
from (
select
v.DATA_DATE,
v.HR,
sv.submission_value_id
from value v
inner join submission_value sv on sv.value_id = v.value_id
where sv.SUBMISSION_VALUE_ID NOT IN (
SELECT SUBMISSION_VALUE_ID FROM VALUE_FLAG WHERE VALUE_FLAG.FLAG_ID = v_Flag_id
);
BEGIN
OPEN hours;
LOOP
FETCH hours into l_hr;
EXIT WHEN hours%NOTFOUND;
AGG_HOURLY_REG_FINAL(l_hr.RHR);
END LOOP;
CLOSE hours;
END RUN_AGG;
The error that I am receiving is as follows:
Error(6,1): PLS-00103: Encountered the symbol "DECLARE" when expecting one
of the following: begin function pragma procedure subtype type <an
identifier> <a double-quoted delimited-identifier> current cursor delete
exists prior external language
Use the following :
CREATE OR REPLACE PROCEDURE RUN_AGG IS
l_rhr VARCHAR2 (100);
l_sub_vl_id VARCHAR2 (100);
CURSOR hours is
SELECT distinct (HR) as RHR, submission_value_id
FROM (SELECT v.DATA_DATE, v.HR, sv.submission_value_id
FROM value_ v
INNER JOIN submission_value sv
ON (sv.value_id = v.value_id)
WHERE sv.SUBMISSION_VALUE_ID NOT IN
(SELECT SUBMISSION_VALUE_ID
FROM VALUE_FLAG
WHERE VALUE_FLAG.FLAG_ID in
(SELECT flag_id
FROM flag
WHERE flag_tx = 'Processed / Calculated')));
BEGIN
OPEN hours;
LOOP
FETCH hours INTO l_rhr, l_sub_vl_id;
EXIT WHEN hours%NOTFOUND;
AGG_HOURLY_REG_FINAL(l_rhr);
END LOOP;
CLOSE hours;
END RUN_AGG;
remove declare
take select flag_id into v_Flag_id from flag where flag_tx =
'Processed / Calculated'; sql in hours cursor's select. So, remove v_Flag_id variable.
return two variables for two columns l_rhr and l_sub_vl_id.
I replaced the name of the table value with value_, since it's a
reserved keyword for oracle.

ORA-01422: exact fetch returns more than requested number of rows ORA-06512: at line 34

for this particular block, i am continuously getting
ora 0142 : exact fetch returns more than requested number of rows
, i have tried distinct, rank and rownum, but nothing seems to work.
begin
for i in c1 loop
if i.estacao_a2 is not null then
begin
select migrationidentifier
into v_master_location
from (
select com.migrationidentifier
, row_number () over (partition by com.migrationidentifier order by com.migrationidentifier asc) RK
from com_location com
where round (i.latitude_a_decimal, 1) =
round (com.LATITUDEWGS84, 1)
and round (i.longitude_a_decimal, 1) =
round (com.longitudewgs84, 1)
and com.sourcedomain = 'FENIX'
)
where rk=1
;
exception
when no_data_found
then dbms_output.put_line ( 'NO RECORDS FOUND IN COM_LOCATION FOR LATITUDE:' || i.latitude_a_decimal);
end;
end if;
end loop;
end;
OK, so you have more than one migrationidentifier in com_location for that set of latitude_a_decimal and longitude_a_decimal. Is this bad data? Or possible? Or there is some ordering criteria that will determine which one are you supposed to take?
If there is an ordering criteria - add that to your query then put the query into a cursor and do an OPEN...FETCH INTO ... CLOSE to grab that row first and populate your variable. You won't need your EXCEPTION block doing it this way, you instead after the fetch do IF cursorname%NOTFOUND THEN dbms_output() ENDIF;
declare
cursor get_migrationidentifier (in_lat_decimal number, in_long_decimal number)
IS
select migrationidentifier from
(select com.migrationidentifier
,row_number () over (partition by com.migrationidentifier order by com.migrationidentifier asc) RK
from com_location com
where round (i.latitude_a_decimal, 1) =
round (com.LATITUDEWGS84, 1)
and round (i.longitude_a_decimal, 1) =
round (com.longitudewgs84, 1)
and com.sourcedomain = 'FENIX') where rk=1
order by migrationidentifier ;
begin
for i in c1
loop
if i.estacao_a2 is not null then
OPEN get_migrationidentifier (i.latitude_a_decimal. i.longitude_a_decimal);
FETCH get_migrationidentifier INTO v_master_location;
IF get_migrationidentifier%NOTFOUND
THEN v_master_location := null;
dbms_output.
put_line (
'NO RECORDS FOUND IN COM_LOCATION FOR LATITUDE:'
|| i.latitude_a_decimal);
end IF;
CLOSE get_migrationidentifier;
end if;
end loop;

why i am getting no data found error?

to a void this error i just make to variable so if there record return then do else do
but i am still getting this error anyone can help me to get out of that ?
thats worked at first query but not the query on line 35
can i use sql%rowcount instead ?
declare
cust_id bmh.info.CUSTOMER_ID#prod%type; --get the id of sp number
num number; -- count of records in rated_rejectes_calls_cursor
num1 number; -- count of records in rated_rejectes_calls_cursor
V_CUST_INFO_CUSTOMER_ID FI_MASAAD.FEB_PRD_14_VIEW.CUST_INFO_CUSTOMER_ID#rtx%type;
V_INITIAL_START_TIME_TIMESTAMP FI_MASAAD.FEB_PRD_14_VIEW.INITIAL_START_TIME_TIMESTAMP#rtx%type;
cursor rated_rejectes_calls_cursor is
select S_P_NUM,CALL_START_TIME
from fi_sdine.rejected_calls_87#prod
where UPPER (STATUS)='RATED';
begin
for rated_rejectes_calls_rec in rated_rejectes_calls_cursor
loop
select count(*) into num from bmh.info#prod where dn_num=rated_rejectes_calls_rec.S_P_NUM;
if num <>0 then
select CUSTOMER_ID into cust_id from bmh.info#prod where dn_num=rated_rejectes_calls_rec.S_P_NUM;
dbms_output.put_line('SP number, '||rated_rejectes_calls_rec.S_P_NUM||' ID is, '||cust_id||' and call start time, '||rated_rejectes_calls_rec.CALL_START_TIME);
select count(*) into num1
from FI_MASAAD.MAR_14_VIEW#rtx a
where CUST_INFO_CUSTOMER_ID =cust_id
and INITIAL_START_TIME_TIMESTAMP=rated_rejectes_calls_rec.CALL_START_TIME;
elsif num1 <> 0 then
select CUST_INFO_CUSTOMER_ID, INITIAL_START_TIME_TIMESTAMP into V_CUST_INFO_CUSTOMER_ID,V_INITIAL_START_TIME_TIMESTAMP
from FI_MASAAD.MAR_14_VIEW#rtx a
where CUST_INFO_CUSTOMER_ID =cust_id
and INITIAL_START_TIME_TIMESTAMP=rated_rejectes_calls_rec.CALL_START_TIME
group by CUST_INFO_CUSTOMER_ID,INITIAL_START_TIME_TIMESTAMP;
elsif num1 =0 then
dbms_output.put_line('tickets not found, '||rated_rejectes_calls_rec.S_P_NUM);
elsif num=0 then
dbms_output.put_line('SP number ID not found, '||rated_rejectes_calls_rec.S_P_NUM);
end if;
end loop;
end;
thank you all in advance
Use nested begin blocks..
BEGIN
--statements
BEGIN
select CUSTOMER_ID into cust_id from bmh.info#prod where dn_num=rated_rejectes_calls_rec.S_P_NUM;
EXCEPTION WHEN NO_DATA_FOUND THEN
--Handle Exception for No Data here
END;
EXCEPTION WHEN OTHERS THEN
-- Final Exceptions go here
END;
/

Resources