Not able get data for today - sql

I have below procedure MY_PROC.
CREATE PROCEDURE MY_PROC(
IN_VAR_FROM_DATE IN VARCHAR2,
OUT_DATA OUT SYS_REFCURSOR )
AS
TEMP_DATE DATE;
BEGIN
TEMP_DATE : = NVL(TO_DATE(IN_VAR_FROM_DATE,'DD-MON-RRRR'),SYSDATE);
IF(IN_VAR_FROM_DATE='CM') THEN
TEMP_DATE := SYSDATE;
END IF;
OPEN OUT_DATA FOR SELECT * FROM TABLE_NAME WHERE DATE_COLUMN>=TRUNC(TEMP_DATE );
EXCEPTION
WHEN OTHERS THEN
NULL;
END MY_PROC;
Now in above proc, When i am passing null as input param, i am getting values for sysdate. i want same when i will pass "CM" as input param but instead i am getting no data.
Please help. Thanks in advance.

Hmmm. . . I think this is the logic you want:
OPEN OUT_DATA FOR
SELECT *
FROM TABLE_NAME
WHERE DATE_COLUMN >= (CASE WHEN IN_VAR_FROM_DATE IS NULL OR IN_VAR_FROM_DATE = 'CM'
THEN TRUNC(sysdate)
ELSE TO_DATE(IN_VAR_FROM_DATE, 'DD-MON-RRRR')
END);

I think this is due to when you are passing 'CM' as input parameter your procedure tries to convert the CM in to date and you are getting exception in this case.
CREATE PROCEDURE MY_PROC(
IN_VAR_FROM_DATE IN VARCHAR2,
OUT_DATA OUT SYS_REFCURSOR )
AS
TEMP_DATE DATE;
BEGIN
IF(IN_VAR_FROM_DATE='CM') THEN
TEMP_DATE := SYSDATE;
ELSE
TEMP_DATE : = NVL(TO_DATE(IN_VAR_FROM_DATE,'DD-MON-RRRR'),SYSDATE);
END IF;
OPEN OUT_DATA FOR SELECT * FROM TABLE_NAME WHERE DATE_COLUMN>=TRUNC(TEMP_DATE );
EXCEPTION
WHEN OTHERS THEN
NULL;
END MY_PROC;

Related

Can we pass partition as parameter in stored procedure ? I'm getting following error

Can we pass partition as parameter in stored procedure ? I'm getting following error.
Please help on this.
CREATE OR REPLACE PROCEDURE PROCEDURE_NAME (PARTITION_NAME IN VARCHAR2)
IS
LASTDATE VARCHAR2(12);
ENDDATE VARCHAR2(12);
BEGIN
IF PARTITION_NAME='DEC_2014' OR PARTITION_NAME='JAN_2015' OR PARTITION_NAME='MAR_2015' OR PARTITION_NAME='MAY_2015' OR PARTITION_NAME='JUL_2015' OR PARTITION_NAME='AUG_2015' OR PARTITION_NAME='OCT_2015' OR PARTITION_NAME='DEC_2015' OR PARTITION_NAME='JAN_2016' THEN
ENDDATE:='31';
ELSIF PARTITION_NAME='NOV_2014' OR PARTITION_NAME='APR_2015' OR PARTITION_NAME='JUN_2015' OR PARTITION_NAME='SEP_2015' OR PARTITION_NAME='NOV_2015' THEN
ENDDATE:='30';
ELSE
ENDDATE:='28';
END IF;
LASTDATE:=CONCAT(CONCAT(ENDDATE,'-'),REPLACE (PARTITION_NAME, '_', '-'));
DBMS_OUTPUT.PUT_LINE(LASTDATE);
DBMS_OUTPUT.PUT_LINE(PARTITION_NAME);
UPDATE
/*+ PARALLEL(Alias 4) */
TABLE_NAME PARTITION (PARTITION_NAME) Alias
SET Alias.Alias_D_EFFECTIVE_DATE =
(SELECT
/*+ PARALLEL(Alias3 4) */
ALAIS2.ALAIS2_D_DATETIME
FROM schema1.TABLE_2 ALAIS2
WHERE TRUNC(ALAIS2_D_DATETIME) <= TO_DATE(LASTDATE,'DD-MON-YYYY')
AND ALAIS2.ALAIS2_N_TRN_ID = Alias.Alias_N_PR
)
WHERE EXISTS
(SELECT Alias3.ALAIS2_D_DATETIME
FROM schema1.TABLE_2 Alias3
WHERE TRUNC(Alias3.ALAIS2_D_DATETIME) <= TO_DATE(LASTDATE,'DD-MON-YYYY')
AND Alias3.ALAIS2_N_TRN_ID = Alias.Alias_N_PR
);
COMMIT;
END PROCEDURE_NAME;
Error:
Error at line 1
ORA-02149: Specified partition does not exist
ORA-06512: at "schema1.PROCEDURE_NAME", line 17
ORA-06512: at line 1
I think you can do by Dynamic SQL Statements, EXECUTE IMMEDIATE Statement
follow this link ...
https://docs.oracle.com/cd/B10501_01/appdev.920/a96590/adg09dyn.htm
https://docs.oracle.com/cloud/latest/db112/LNPLS/dynamic.htm#LNPLS01115
CREATE OR REPLACE PROCEDURE PROCEDURE_NAME (PARTITION_NAME IN VARCHAR2)
IS
LASTDATE VARCHAR2(12);
ENDDATE VARCHAR2(12);
query_str VARCHAR2(1000);
BEGIN
//.......your code.......
query_str := 'UPDATE TABLE_NAME PARTITION (' || PARTITION_NAME || ') Alias '
||'SET Alias.Alias_D_EFFECTIVE_DATE =.....'
EXECUTE IMMEDIATE query_str;
COMMIT;
END PROCEDURE_NAME;
Hope this will work.

Trigger compilation error

I need some help in creating a trigger.
create or replace trigger trigger_one
before insert on Funtom_timesheet
for each row
Declare
V_id number;
V_hours number;
Begin
Select max(timesheet_ID)+1 into v_id from Funtom_timesheet
:new.timesheet_ID :=v_id;
select grade_hours into V_hours
from funtom_grade join funtom_employee
on emp_grade = grade_id
where empid = :new.timesheet_emp;
if V_hours >:new.timesheet_hours
else
:new.timesheet_overtime :=
:new.timesheet_hours-V_hours
:new.timesheet_hours:= V_hours;
END IF;
END;
/
please tell me which part of my code is wrong so I could work on it,
Thanks
You have many syntax errors - missing ; and then. There can't be if only with else part and without expression on it.
CREATE OR REPLACE TRIGGER TRIGGER_ONE
BEFORE INSERT ON FUNTOM_TIMESHEET
FOR EACH ROW
DECLARE
V_ID NUMBER;
V_HOURS NUMBER;
BEGIN
SELECT MAX(TIMESHEET_ID) + 1 INTO V_ID FROM FUNTOM_TIMESHEET;
:NEW.TIMESHEET_ID := V_ID;
SELECT GRADE_HOURS
INTO V_HOURS
FROM FUNTOM_GRADE
JOIN FUNTOM_EMPLOYEE
ON EMP_GRADE = GRADE_ID
WHERE EMPID = :NEW.TIMESHEET_EMP;
IF V_HOURS > :NEW.TIMESHEET_HOURS THEN
NULL;
ELSE
:NEW.TIMESHEET_OVERTIME := :NEW.TIMESHEET_HOURS - V_HOURS;
:NEW.TIMESHEET_HOURS := V_HOURS;
END IF;
END;
/
Also better use SEQUENCES instead of:
SELECT MAX(TIMESHEET_ID) + 1 INTO V_ID FROM FUNTOM_TIMESHEET;
:NEW.TIMESHEET_ID := V_ID;
When selecting form the same table as inserting, you can get MUTATING trigger error (http://www.dba-oracle.com/t_avoiding_mutating_table_error.htm)

Overlap function in Oracle

I'm writing a package to learn Oracle. I want to create an OVERLAP function that checks if two date ranges overlap each other.
FUNCTION OVERLAP(p_START_DATE_1 DATE, p_END_DATE_1 DATE,
p_START_DATE_2 DATE, p_END_DATE_2 DATE) RETURN VARCHAR2 AS
lv_RESULT VARCHAR2(1);
BEGIN
lv_RESULT := SELECT 'T' AS overlap FROM dual
WHERE (p_START_DATE_1, p_END_DATE_1) overlaps (p_START_DATE_2, p_END_DATE_2);
IF (lv_RESULT = 'T')
RETURN 'T';
RETURN 'N';
END OVERLAP;
I tried to execute my function, but getting an error ORA-04063: package body 'XYZ' contains errors...
SELECT KP_XYZ_PACKAGE_SQL.OVERLAP(
TO_DATE('01/01/2014', 'DD/MM/YYYY'),
TO_DATE('01/12/2014', 'DD/MM/YYYY'),
TO_DATE('01/02/2014', 'DD/MM/YYYY'),
TO_DATE('01/05/2014', 'DD/MM/YYYY'))
FROM DUAL;
I think SELECT works fine. But the error occurs (I suppose) here: lv_RESULT := SELECT.... Why?
Try this:
CREATE OR REPLACE FUNCTION OVERLAP(p_START_DATE_1 DATE, p_END_DATE_1 DATE,
p_START_DATE_2 DATE, p_END_DATE_2 DATE) RETURN VARCHAR2 AS
lv_RESULT VARCHAR2(1);
BEGIN
lv_RESULT := 'N';
SELECT 'T' into lv_RESULT FROM dual
WHERE (p_START_DATE_1, p_END_DATE_1) overlaps (p_START_DATE_2, p_END_DATE_2);
IF (lv_RESULT = 'T') THEN
RETURN 'T';
END IF;
RETURN 'N';
END OVERLAP;
The IF statement was incomplete too - THEN and END IF were missing, which I have now added.
The documentation for SELECT INTO statement is here. There are links to examples at the end of the page.
Corrected version : return 'T' for True 'N' for False (?)
CREATE OR REPLACE FUNCTION OVERLAP(p_START_DATE_1 DATE, p_END_DATE_1 DATE,
p_START_DATE_2 DATE, p_END_DATE_2 DATE) RETURN VARCHAR2 AS
lv_RESULT VARCHAR2(1);
BEGIN
SELECT 'T' into lv_RESULT FROM dual WHERE (p_START_DATE_1, p_END_DATE_1) overlaps (p_START_DATE_2, p_END_DATE_2);
RETURN lv_RESULT;
EXCEPTION
WHEN NO_DATA_FOUND THEN lv_RESULT := 'N';
RETURN lv_RESULT;
END OVERLAP;
/

How to display output in Pl/SQL

I was wondering if someone can help me figure out how to code so that it will display the output without me having to use the command select * from month_days when I run the program.
set serveroutput on
--- Drop Table
DROP TABLE MONTH_DAYS;
--- Create Table
CREATE TABLE MONTH_DAYS(cnt number(2), Month_ Varchar(9),Days_ Number(2));
Declare
mons varchar2(10);
dats varchar2(10);
i Binary_integer := 0;
Begin
loop
i:= i+1;
if i = 13 then
exit;
end if;
insert into month_days(cnt, month_, days_)`enter code here`
values
(i, to_char(add_months(to_date('20200112', 'YYYYDDMM'), i), 'Month'),
to_char(last_day(add_months(to_date('20200112', 'YYYYDDMM'), i)), 'DD'));
end loop;
DBMS_Output.Put_Line('The Month and Days for the year 2020'||Month_|| ''||Days_);
end;
Create or Replace function insert_date (mons varchar2, dats varchar2)
return varchar2
as
i Binary_integer := 0;
Begin
loop
i:= i+1;
if i = 13 then
exit;
end if;
insert into month_days(cnt, month_, days_)
//enter code here Didn't understood what you are trying to do here
values
(i, to_char(add_months(to_date('20200112', 'YYYYDDMM'), i), 'Month'), to_char(last_day(add_months(to_date('20200112', 'YYYYDDMM'), i)), 'DD'));
end loop;
return 'The Month and Days for the year 2020'||Month_|| ''||Days_;
end;
select insert_date(12,2) from dual;
Is this what you are looking for ??
I haven't tested this. I think it should work.
Use:
select
rownum cnt,
to_char(add_months(date '2020-12-01', rownum), 'Month') month_,
to_char(last_day(add_months(date '2020-12-01', rownum)), 'DD')) days_
from
dual
connect by
level <= 12;
If you're using sqlplus, try turning serveroutput on by using the following command.
set serveroutput on
if using another client program, look up the documentation for enabling server output.

IF else condition in sql stored procedure

I'm trying to compile the stored procedure:
create
procedure checkFroud2(code IN varchar2, p_recordset OUT SYS_REFCURSOR)
AS
BEGIN
OPEN p_recordset FOR
if code='C' then
select * from emp
//dbms_output.putline('this is if block')
else if code='F' then
dbms_output.putline('this is else block')
else
dbms_output.putline('last else')
end if;
end checkFroud2;
but this is showing compile time errors. Can anybody suggest where the problem is?
CREATE
PROCEDURE checkFroud2(
code IN VARCHAR2,
p_recordset OUT SYS_REFCURSOR)
AS
BEGIN
IF code='C' THEN
dbms_output.put_line('this is if block');
OPEN p_recordset FOR
SELECT * FROM emp;
ELSIF code='F' THEN
--you can open p_recordset with dummy as
/*open p_recordset for select * from dual where 1 = 0; */
dbms_output.put_line('this is else block');
ELSE
/*open p_recordset for select * from dual where 1 = 0; */
dbms_output.put_line('last else');
END IF;
END checkFroud2;
/
var o refcursor;
BEGIN
CHECKfroud2
('C',:o);
END;
/
PRINT O;
The correct code is as follows:
create procedure checkFroud2(code IN varchar2, p_recordset OUT SYS_REFCURSOR)
AS
BEGIN
OPEN p_recordset FOR
if code='C' then
select * from emp
//dbms_output.putline('this is if block');
elsif code='F' then
dbms_output.putline('this is else block');
else
dbms_output.putline('last else');
end if;
end checkFroud2;
ELSE IF doesn't exist use ELSIF, also remove // before dbms_output.putline('this is if block').
This is an example in oracle 11g
CREATE OR REPLACE PROCEDURE PROC_EMP_CHECK
(
EMPNO1 IN NUMBER
, EMPNO2 IN NUMBER
)
AS
EMPONE_NOT_EXISTS EXCEPTION;
EMPTWO_NOT_EXISTS EXCEPTION;
BOTHEMP_NOT_EXISTS EXCEPTION;
EMPCOUNT1 NUMBER;
EMPCOUNT2 NUMBER;
BEGIN
SELECT COUNT(1) INTO EMPCOUNT1 FROM EMPLOYEES WHERE EMPLOYEE_ID=EMPNO1;
SELECT COUNT(1) INTO EMPCOUNT2 FROM EMPLOYEES WHERE EMPLOYEE_ID=EMPNO2;
BEGIN
IF( EMPCOUNT1=0 AND EMPCOUNT2=0)THEN
RAISE BOTHEMP_NOT_EXISTS;
ELSIF ( EMPCOUNT1=0) THEN
RAISE EMPONE_NOT_EXISTS;
ELSIF ( EMPCOUNT2=0) THEN
RAISE BOTHEMP_NOT_EXISTS;
dbms_output.put_line('ELSE BLOCK');
END IF;
END;
EXCEPTION
WHEN EMPONE_NOT_EXISTS THEN
dbms_output.put_line('EMP One not exit');
WHEN EMPTWO_NOT_EXISTS THEN
dbms_output.put_line('EMP two not exit');
WHEN BOTHEMP_NOT_EXISTS THEN
dbms_output.put_line('both not exit');
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END PROC_EMP_CHECK;
Use ELSIF instead of ELSE IF. By using ELSE IF you're opening up a new nested IF-block, which you're not closing.
Couple of errors:
1. Open record set for ??? For what??
2. ELSIF and no ELSE IF
3. where is ;
CREATE PROCEDURE CHECKFROUD2 ( CODE IN VARCHAR2,
P_RECORDSET OUT SYS_REFCURSOR )
AS
BEGIN
OPEN P_RECORDSET FOR SELECT * FROM DUAL;
IF CODE = 'C'
THEN
SELECT * FROM EMP;
ELSIF CODE = 'F'
THEN
DBMS_OUTPUT.PUTLINE ( 'this is else block' );
ELSE
DBMS_OUTPUT.PUTLINE ( 'last else' );
END IF;
END CHECKFROUD2;