I am stuck at comparing two dates in plsql programming.
I have 2 stored procedures. The first stored procedure returns me date column as OUT param.
I am passing 1st output param is as input param for 2nd stored procedure.
But my query not returning correct value.
Stored procedure #1:
PROCEDURE SP_FIRST_COMPLETE(TASK_ID IN VARCHAR2, FIRST_COMPLETE_DT OUT DATE)
IS
...
BEGIN
...
...
DBMS_OUTPUT.PUTLINE('First completed dt is:= '||FIRST_COMPLETE_DT);
.....
end;
Stored procedure #2:
PROCEDURE SP_NOT_FIRST_COMPLETE(TASK_ID IN VARCHAR2, FIRST_COMPLETE_DT IN DATE, FIRST_COMPLETE_DT1 OUT DATE)
IS
....
BEGIN
DBMS_OUTPUT.PUTLINE('First completed dt is:= '||FIRST_COMPLETE_DT);
FOR R_ROW IN (SELECT ........ FROM .... WHERE EVENT_DT > FIRST_COMPLETE_DT ORDER BY EVENT_DT
LOOP
DBMS_OUTPUT.PUTLINE('First completed dt is:= '||FIRST_COMPLETE_DT||' QUERY RESULT DATE :='||R_ROW.EVENT_DT);
.....
END;
1ST STORED PROC OUTPUT
First completed dt is:= 14-FEB-14
2ND STORED PROC OUTPUT
First completed dt is:= 14-FEB-14
First completed dt is:= 14-FEB-14 QUERY RESULT DATE := 28-FEB-12
When I run query in SQL its giving correct result.
select ... from.... where event_dt > '18-FEB-14' order by event_dt;
Please help in in this.
Thanks
Sarma
Please look to to what it should be and compare to your code:
CREATE OR REPLACE PROCEDURE SP_FIRST_COMPLETE (
TASK_ID IN VARCHAR2,
FIRST_COMPLETE_DT IN OUT DATE)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE ('First date is:= ' ||
TO_DATE(FIRST_COMPLETE_DT, 'DD-MM-YYYY', 'NLS_DATE_LANGUAGE=ENGLISH')
);
END;
CREATE OR REPLACE PROCEDURE SP_NOT_FIRST_COMPLETE (
TASK_ID IN VARCHAR2,
FIRST_COMPLETE_DT IN DATE,
FIRST_COMPLETE_DT1 OUT DATE)
IS
BEGIN
FIRST_COMPLETE_DT1 := TO_DATE(FIRST_COMPLETE_DT, 'DD-MM-YYYY', 'NLS_DATE_LANGUAGE=ENGLISH');
DBMS_OUTPUT.PUT_LINE ('Second date is:= ' || FIRST_COMPLETE_DT1);
END;
The execution
DECLARE
THE_OUTPUT_DATE1 DATE ;
THE_OUTPUT_DATE2 DATE ;
BEGIN
THE_OUTPUT_DATE1 := SYSDATE;
SP_FIRST_COMPLETE (1, THE_OUTPUT_DATE1);
SP_NOT_FIRST_COMPLETE (1, THE_OUTPUT_DATE1, THE_OUTPUT_DATE2);
DBMS_OUTPUT.PUT_LINE('Output date ' || TO_DATE(THE_OUTPUT_DATE2, 'DD-MM-YYYY', 'NLS_DATE_LANGUAGE=ENGLISH'));
END;
the DBMS output then as what you want:
First Date is:= 06-APR-14
Second Date is:= 06-APR-14
Output date: 06-APR-14
Related
I have written the following PLSQL procedure:
create or replace procedure lrt_bericht (current_date in VARCHAR2, last_date in VARCHAR2) as
calendar_week VARCHAR2(10);
BEGIN
calendar_week := EXTRACT(YEAR FROM sysdate)||'_'||to_char(to_date(current_date,'DD.MM.YYYY'),'IW');
delete from astrid_liste_history
where link_to_uts is null;
insert into astrid_liste_bericht
(Link_to_UTS,Incident_Number,CI_Plus,Site_ID,Anzahl_CI_ID,Anzahl_Zellen,Status_690,Service_Affecting,Incident_Work_Info_Notes,Target_Date,Incident_Work_Info_Summary,Assigned_Group,Submit_Date_max,Last_Modified_Day,Region_CI_Plus,WEATHERMAP_LONGTERM,Incident_Summary,Reported_Date,Status,Company,Incident_Notes,Supercluster,CI_Plus_Cons_Top65,CI_Plus_Cons_Region,CI_Plus_Cons_Year,Last_LRI_Update,Link_to_ATEA,Bereich_Gruppe,Connect_Prio,Connect_Pop_Rank,Categorization_Tier_1,Categorization_Tier_2,Categorization_Tier_3,Date_Import,Time_Import)
select *
from astrid_liste_history
where astrid_liste_history.date_import = current_date;
update astrid_liste_bericht
set Closed_In_CW = calendar_week
where
incident_number in
(select incident_number from astrid_liste_bericht where date_import = last_date
and INCIDENT_WORK_INFO_SUMMARY like '%Volker%'
minus
select incident_number from astrid_liste_bericht where date_import = current_date)
;
update astrid_liste_bericht
set Closed_In_CW = NULL
where date_import not in (last_date)
and Closed_In_CW = calendar_week;
update astrid_liste_bericht
set ADPW = 'Yes'
where
closed_in_cw = calendar_week
and upper(INCIDENT_SUMMARY) like '%ADPW%';
update astrid_liste_bericht
set ADPW = 'No'
where
closed_in_cw = calendar_week
and upper(INCIDENT_SUMMARY) not like '%ADPW%';
COMMIT;
END lrt_bericht;
It compiles sucessfully but after trying to execute it:
begin
lrt_bericht('10.11.2019','03.11.2019');
end;
there is no data written into the astrid_liste_bericht table.
However, if I execute manually every step in the procedure, at the end I can see the data being added/updated in the astrid_liste_bericht table.
Do you have any idea why this happens and what should I do in oder to make the data be updated in the astrid_liste_bericht table via the procedure?
This looks to me like an issue with date mismatch. What is the column type of astrid_liste_history.date_import.
Can you run this query and confirm if data comes back from sql prompt
select *
from astrid_liste_history
where astrid_liste_history.date_import = current_date ;
Replace this current_date with whatever date you are passing to Proc.
Adding test script
CREATE OR REPLACE PROCEDURE temp_proc
(
current_date1 IN VARCHAR2
,last_date IN VARCHAR2
) AS
calendar_week VARCHAR2(10);
BEGIN
calendar_week := extract(YEAR FROM SYSDATE) || '_' ||
to_char(to_date(current_date, 'DD.MM.YYYY'), 'IW');
INSERT INTO temp
(temp1)
SELECT 1 FROM temp2 WHERE temp2.date_import = current_date1;
COMMIT;
END temp_proc;
/
CREATE TABLE temp(temp1 VARCHAR2(100));
/
CREATE TABLE temp2(date_import VARCHAR2(100));
/
INSERT INTO temp2 VALUES('10.11.2019')
SELECT 1 FROM temp2 WHERE temp2.date_import = '10.11.2019';
SET serveroutput ON
BEGIN
temp_proc('10.11.2019', NULL);
END;
/
select *
from temp;
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;
Good Morning .
I got stuck in sql query . Please can you help me here.
problem statement: I have to calculate the execution time of one query in stored procedure.
There are about 150 queries in stored procedure and I have to store this execution time in one table . please help me here .
Because of some confidentiality, I cant provide the data.
please find dummy data
CREATE OR REPLACE PROCEDURE test (p_fromdate DATE)
AS
fromdate DATE;
todate DATE;
c1 number;
c2 number;
c3 number;
BEGIN
fromdate := p_fromdate;
todate := p_fromdate;
select count(*) into c1 from employee;
select count(*) into c1 from mngr;
select count(*) into c1 from hr;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
DBMS_OUTPUT.put_line ( SQLERRM
|| '~'
|| 'Data not populated for'
|| p_fromdate
);
END test;
Table a:
PROTOCOL VARCHAR2(20)
Table b:
YEAR NUMBER(4)
MONTH VARCHAR2(20)
PROTOCOL VARCHAR2(20)
DATE1 DATE
My procedure code:
CREATE PROCEDURE his
#Year NUMBER(4),
#Month VARCHAR2(20)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION trninsert
DECLARE ##date DATE
SET ##date = sysdate;
INSERT INTO b (Year, month, date1, protocol)
(select #Year, #Month, ##date,* from a)
COMMIT TRANSACTION trninsert
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION trninsert
END CATCH
END
I am using plsql developer and it is showing errors in procedure.
you've written this a mysql type syntax.
oracle would be:
CREATE PROCEDURE his(p_year b.year%type,
p_month b.month%type)
AS
BEGIN
INSERT INTO b (Year, month, date1, protocol)
select p_year, p_month, sysdate, a.protocol
from a;
commit;
END;
though its bad form to commit in the procedure.
eg:
SQL> CREATE PROCEDURE his(p_year b.year%type,
2 p_month b.month%type)
3 AS
4 BEGIN
5 INSERT INTO b (Year, month, date1, protocol)
6 select p_year, p_month, sysdate, a.protocol
7 from a;
8 commit;
9 END;
10 /
Procedure created.
SQL> insert into a values('prot a');
1 row created.
SQL> exec his(2012, 10)
PL/SQL procedure successfully completed.
SQL> select * from b;
YEAR MONTH PROTOCOL DATE1
---------- -------------------- -------------------- ---------
2012 10 prot a 06-FEB-13
SQL>
Your procedure is not in a valid format: Change your entire structure with,
CREATE [OR REPLACE] PROCEDURE procedure_name
[ (parameter [,parameter]) ]
IS
[declaration_section]
BEGIN
executable_section
[EXCEPTION
exception_section]
END [procedure_name];
For more parameters: Click here
yeah you have not use the plsql syntax:
Code will be:
CREATE OR REPLACE PROCEDURE his
(Year b.year%type,
Month b.month%type)
AS
BEGIN
INSERT INTO b (Year, month, date1, protocol)
VALUES select Year, Month, sysdate,a.protocol from a ;
COMMIT;
END;
I am trying to write a procedure to check if parameters given (dates) lie between any of the existing dates in the table. And if not insert new row.
CREATE OR REPLACE PROCEDURE test(date1 IN DATE, date2 IN DATE) AS
ddate1 DATE;
ddate2 DATE;
quer VARCHAR2(50);
BEGIN
SELECT fdate, tdate INTO ddate1, ddate2 FROM dataHolder;
IF (ddate1 < date1) AND (ddate2 > date2) THEN
quer := 'invalid';
ELSE
INSERT INTO dataHolder VALUES (date1, date2);
quer := 'success';
END IF;
DBMS_OUTPUT.PUT_LINE(quer);
END;
/
I have tried something like this but when executed I get this error:
ORA-01422: exact fetch returns more than requested number of rows
You are getting that error because your select statement returns more than one record. To simplify the process you could use merge statement and rewrite your procedure as follows:
CREATE OR REPLACE PROCEDURE test(date1 IN DATE, date2 IN DATE) AS
BEGIN
merge into Dataholder dh
using dual
on ((date1 < dh.fdate) and (date2 < dh.tdate))
when not matched then
insert (dh.fdate, dh.tdate)
values(date1, date2);
if sql%rowcount > 0
then
dbms_output.put_line('success');
else
dbms_output.put_line('invalid');
end if;
END;
Your select statement fetches more than record whereas your code expects only one, since you're fetching into single-value variables. You could use BULK COLLECT and collect all the dates into a collection of dates, but I think you can improve on it with the code below:
CREATE OR REPLACE PROCEDURE test(date1 IN DATE, date2 IN DATE) AS
ddate1 DATE;
ddate2 DATE;
invalidRecords NUMBER := 0;
quer VARCHAR2(50);
BEGIN
SELECT COUNT(1) INTO invalidRecords FROM dataHolder WHERE fdate < date1 AND tdate > date2;
IF (invalidRecords > 0) THEN
quer := 'invalid';
ELSE
INSERT INTO dataHolder VALUES (date1, date2);
quer := 'success';
END IF;
DBMS_OUTPUT.PUT_LINE(quer);
END;
/
Since COUNT(1) will always return just one record, it will never throw an ORA-01422 error. Also, it will always return data, so you don't need to worry about NO_DATA_FOUND, as the value 0 will be fetched if there are no invalid records.
Some small optmization of Nuno Guerreiro's answer
SELECT COUNT(1) INTO invalidRecords
FROM dual
WHERE exists
(SELECT 1 FROM dataHolder WHERE fdate < date1 AND tdate > date2);
It will allow to keep out of counting.