I need to loop in Oracle on monthly basis for 3 years. I am trying for daily basis first and below is my query but not sure about the error.
can you please help with this. I am fairly new to oracle.
DECLARE #StartDT DATE;
SET #StartDT = '20090101'
WHILE #StartDT <= '20090131'
BEGIN
PRINT CONVERT(VARCHAR,#StartDT) + '---' + convert(varchar,DATEADD(DAY,1,#StartDT))
END
What you posted is completely SQL Server syntax. In Oracle, you'd probably do this in SQL
select date '2009-01-01' + level
from dual
connect by level <= 31
If you want to use PL/SQL (and assuming you are using a tool that will display the output from dbms_output which you shouldn't assume will happen in prod), you could do something like this.
declare
l_dt date := date '2009-01-01';
begin
while( l_dt <= date '2009-01-31' )
loop
dbms_output.put_line( to_char( l_dt, 'yyyy-mm-dd' ) );
l_dt := l_dt + 1;
end loop;
end;
In oracle you can use for loop as following:
Begin
For d in (select date '2009-01-01' + level - 1 as dt
from dual
Connect by level <= add_months(date '2009-01-01', 3) - date '2009-01-01')
Loop
dbms_output.put_line(to_char(d.dt, 'yyyy-mm-dd'));
End loop;
End;
/
Cheers!!
Related
I've managed to incorporate variables into my pl/sql script and I get the correct result but I cannot figure out how to get it back in the same format as if I executed a plain select. I only see examples that use dbms_output.put_line which outputs text. How do I get an ordinary table out of this:
declare
monday date;
sunday date;
c sys_refcursor;
type t is table of MY_TABLE%rowtype;
r t;
begin
monday := (sysdate - 7 - to_char(sysdate, 'd') + 2);
sunday := (sysdate - 7 + to_char(sysdate, 'd'));
DBMS_OUTPUT.PUT_LINE(monday);
DBMS_OUTPUT.PUT_LINE(sunday);
select
*
bulk collect into
r
from
MY_TABLE
where
"Created On" >= monday and
"Created On" <= sunday
fetch next 10 rows only;
DBMS_OUTPUT.PUT_LINE(r.COUNT); -- <-- = 10
-- this might work but doesn't yet...
open c for select * from r;
DBMS_SQL.RETURN_RESULT(c);
close c;
end;
I found a way that it might be possible to use a cursor with DBMS_SQL.RETURN_RESULT but I still have issues with the r, it says ORA-00942 that the table name is invalid.
This is the code
declare
a integer;
begin
select to_char(to_date('1/1/2017 ','mm/dd/yyyy') + level -1) into a from dual
connect by level <=365;
for a in 1..3 loop
dbms_output.put_line(a);
end loop;
end;
Error occurring is exact fetch requested more no of rows
Please help
You are trying to get multiple value in a scaler variable.
Try this:
begin
for i in (select to_char(to_date('1/1/2017 ','mm/dd/yyyy') + level -1) col
from dual
connect by level <=365) loop
for j in 1..3 loop
dbms_output.put_line(i.col);
end loop;
end loop;
end;
/
1st of all, please be aware about the fact that you declared the "a" variable as integer but then you assign a varchar2 to it.
2nd, I was testing your code and it seems that there is a problem with level <= 365.
I changed it into level = 365 and it seemed to return the expected result.
declare
a integer;
begin
select to_char(to_date('1/1/2017 ','mm/dd/yyyy') + level -1) into a from dual
-- connect by level <= 365;
connect by level = 365;
for a in 1..3 loop
dbms_output.put_line(a);
end loop;
end;
My oracle version : Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
I'm trying to set a variable outside loop and make its value change as the each item of loop. (Just like we usually do in jsp, php...)
create or replace PROCEDURE TEST2 AS
-- VARIABLE
v_variable number;
cursor c2 is
select round(dbms_random.value() * 8) + 1 AS temp_key from dual; -- temp_key is a random value
BEGIN
OPEN c2;
FOR SRC IN (SELECT * FROM TB_MASTER_TEMP2) -- it has many rows
LOOP
fetch c2 into v_variable; -- v_variable need to change for every row
Dbms_Output.Put_Line(SRC.MAS_ENTRY_NM || ', ' ||v_variable); --test
END LOOP;
END TEST2;
But the result is
aaa, 8
bbb, 8 --`v_variable` stays the same
...
v_variable doesn't change.
Please correnct my procedure.
Unless someone has played silly buggers with it, dual has a single row, so the result set returned by c2 also has a single row. Any attempt to fetch beyond the end of that result set will simply return the last (and only) row over and over again.
If you want to retrieve a different random value on each iteration of the loop, you need to execute your SELECT ... FROM dual each time you loop, as in #Utsav's code.
Try this
create or replace PROCEDURE TEST2 AS
-- VARIABLE
v_variable number;
--cursor c2 is
--select round(dbms_random.value() * 8) + 1 AS temp_key from dual; -- temp_key is a random value
BEGIN
--OPEN c2;
FOR SRC IN (SELECT * FROM TB_MASTER_TEMP2) -- it has many rows
LOOP
--fetch c2 into v_variable; -- v_variable need to change for every row
select round(dbms_random.value() * 8) + 1 into v_variable from dual;
Dbms_Output.Put_Line(SRC.MAS_ENTRY_NM || ', ' ||v_variable); --test
END LOOP;
END TEST2;
Hello i have slightly tweaked your code. It may help you. Since i dont have workspace with me so plz bear with any syntax errors.
CREATE OR REPLACE PROCEDURE TEST2
AS
-- VARIABLE
v_variable NUMBER;
BEGIN
-- OPEN c2; -- Not required
FOR SRC IN
(SELECT t2.*,
ROUND(dbms_random.value() * 8) + 1 AS temp_key
FROM TB_MASTER_TEMP2 t2
) -- it has many rows
LOOP
-- v_variable need to change for every row
Dbms_Output.Put_Line(SRC.MAS_ENTRY_NM || ', ' ||src.temp_key); --test
END LOOP;
END TEST2;
I have a complex stored procedure inside a package. Inside this SP, I need to query a table to get all the data pertaining one column and then use this to check some other condition inside an "IF" statement.
Here is what I am doing:
--declare a variable to store the holidays
l_holidays MySchema. HolidayTable.DateColumn%TYPE
-- populate this variable
Select a.DateColumn into l_holidays
from MySchema. HolidayTable a;
-- using this variable inside an "IF" statement
IF (current_Date IN l_holidays)
THEN
-- do something
ELSE
-- do something
END IF;
Every time I run this, I get the following error
ORA-01422: exact fetch returns more than requested number of rows
I know this is because I am trying to populate the entire column using the "INTO" clause. But I don't know any other way of doing it.
Create a collection and use BULK COLLECT INTO:
CREATE PROCEDURE my_proc (
current_date IN MySchema.HolidayTable.DateColumn%TYPE
)
AS
TYPE date_tab IS TABLE OF MySchema.HolidayTable.DateColumn%TYPE;
l_holidays date_tab;
BEGIN
SELECT DateColumn
BULK COLLECT INTO l_holidays
FROM MySchema.HolidayTable;
IF (current_Date MEMBER OF l_holidays)
THEN
NULL; -- do something
ELSE
NULL; -- do something
END IF;
END;
Otherwise you can just test in the select:
CREATE PROCEDURE my_proc (
current_date IN MySchema.HolidayTable.DateColumn%TYPE
)
AS
has_date NUMBER(1,0);
BEGIN
SELECT CASE WHEN EXISTS ( SELECT 'X'
FROM MySchema.HolidayTable
WHERE DateColumn = Current_Date )
THEN 1
ELSE 0
END
INTO has_date
FROM DUAL;
IF has_date = 1
THEN
NULL; -- do something
ELSE
NULL; -- do something
END IF;
END;
Hello similarly you can use this query to fulfill your requirements
SET serveroutput ON;
SET sqlbl ON;
DECLARE
type l_holiday
IS
TABLE OF DATE;
tab_holiday l_holiday;
BEGIN
SELECT a.dt BULK COLLECT
INTO tab_holiday
FROM
(SELECT SYSDATE dt FROM DUAL
UNION
SELECT SYSDATE+1 dt FROM DUAL
UNION
SELECT SYSDATE+2 dt FROM DUAL
UNION
SELECT SYSDATE+3 FROM DUAL
)a;
IF tab_holiday.COUNT > 0 THEN
IF SYSDATE MEMBER OF tab_holiday THEN
dbms_output.put_line('yes working');
ELSE
dbms_output.put_line('awsme working');
END IF;
END IF;
END;
here is my code:
DECLARE
V_loop number(2); -------declare the loop times
begin
looptimes(V_loop); ------set the forcast times from parameter table
loop
IF V_loop > 0 ------forcast
THEN
IF to_char((sysdate+V_loop-7),'dd/mon/yy') not like To_chat((d.holiday_date),'dd/mon/yy')----------condition that perivous 'day' not holiday
then
insert into local_rm16(tni, lr, frmp, day, hh, volume)
SELECT TNI, LR, FRMP, sysdate+v_loop, HH, AVG(VOLUME)
FROM V_nem_rm16,DBP_holiday d
where to_char(day, 'Day') = to_char(sysdate+V_loop, 'Day')
group by day,hh, lr, frmp,tni
order by 1;
else
exit;
end if;
V_loop := V_loop -1;
ELSE
exit;
ENd if;
END loop;
end;
i dont know howto declare holiday_date in if conditions, can anyone help me, thx
You have written to_chat instead of to_char:
IF to_char((sysdate+V_loop-7),'dd/mon/yy') not like To_chat((d.holiday_date),'dd/mon/yy')
You can't use d before you defined it. It's defined in SELECT as an alias to DBP_holiday table, but you use it earlier in IF expression. You should think once again about your code, because you can't do it like this (maybe you should consider using cursor loop).