问题
I have written a query to extract hours between dates. This will basically retrieve the time entry for the employee. When I am executing the below query, It is working fine but when i add the extract function I am getting an error :
ORA-30076: invalid extract field for extract source
select emp_id, start_date , stop_date ,
(ROUND(SUM(
(EXTRACT (DAY FROM line_stop_time - line_start_time)*(3600*24))
+ (EXTRACT (HOUR FROM line_stop_time - line_start_time)*(3600))
+ (EXTRACT (MINUTE FROM line_stop_time - line_start_time)*(60))
+ (EXTRACT (SECOND FROM line_stop_time- line_start_time)*1)
) / (3600), 2) )recorded
from
(SELECT DISTINCT papf.person_number emp_id,
( To_char (sh21.start_time, 'DD-MM-YYYY') ) start_date,
( To_char (sh21.stop_time, 'DD-MM-YYYY') ) stop_date,
To_char(sh21.start_time, 'HH24:MI') line_start_time,
To_char(sh21.stop_time, 'HH24:MI') line_stop_time
FROM per_all_people_f papf,
per_all_assignments_m asg,
per_legal_employers ple,
hwm_tm_rec sh21,
hwm_tm_rec_grp_usages sh22,
hwm_tm_rec_grp sh23,
-- hwm_tm_rec_grp sh29,
hwm_grp_type sh24,
hwm_tm_rep_atrb_usages sh25,
hwm_tm_rep_atrbs sh26,
hwm_tm_statuses sh27,
hwm_tm_status_def_b sh28
WHERE papf.person_id = asg.person_id(+)
AND asg.legal_entity_id = ple.organization_id
AND asg.primary_flag = 'Y'
AND asg.assignment_status_type = 'ACTIVE'
AND ple.status = 'A'
AND Trunc (SYSDATE) BETWEEN papf.effective_start_date AND
papf.effective_end_date
AND Trunc (SYSDATE) BETWEEN asg.effective_start_date AND
asg.effective_end_date
AND Trunc (SYSDATE) BETWEEN ple.effective_start_date AND
ple.effective_end_date
AND papf.person_number = '55'
AND sh21.latest_version = 'Y'
AND sh21.resource_type = 'PERSON'
AND sh21.tm_rec_id = sh22.tm_rec_id
AND sh21.tm_rec_version = sh22.tm_rec_version
AND sh21.layer_code = 'TIME_RPTD'
AND sh22.layer_code = 'TIME_RPTD'
AND sh22.tm_rec_grp_id = sh23.tm_rec_grp_id
AND sh22.tm_rec_grp_version = sh23.tm_rec_grp_version
AND sh23.latest_version = 'Y'
AND sh21.resource_id = sh23.resource_id
AND sh23.grp_type_id = sh24.grp_type_id
--AND sh25.usages_source_id =sum.TM_REC_GRP_ID
AND sh21.tm_rec_id = sh25.usages_source_id
AND sh21.tm_rec_version = sh25.usages_source_version
AND sh25.usages_type = 'TIME_RECORD'
AND sh24.name = 'Processed TimecardDay'
AND sh25.tm_rep_atrb_id = sh26.tm_rep_atrb_id
AND sh26.attribute_category IN (SELECT base_element_name
FROM pay_element_types_f)
AND sh21.resource_id = papf.person_id
AND sh21.tm_rec_type IN ( 'RANGE', 'MEASURE' )
AND sh27.tm_status_def_id = sh28.tm_status_def_id
AND sh27.tm_bldg_blk_id = sh21.tm_rec_id
AND sh27.tm_bldg_blk_version = sh21.tm_rec_version
ORDER BY papf.person_number,
( To_char (sh21.start_time, 'DD-MM-YYYY') ) DESC)
group by emp_id, start_date , stop_date
How can i change the extract function to give me the same result. Is there an alternative for extract function to give the same results ?
回答1:
Try converting your columns to date first to avoid error...:
EXTRACT (DAY FROM to_date(line_stop_time , 'dd-mm-yyyy'))
- EXTRACT (DAY FROM to_date(line_start_time, 'dd-mm-yyyy'))
Here is the DEMO.
And for the HOUR, MINUTE and SECOND use the format mask 'dd-mm-yyyy hh24:mi:ss'
Hope this will help!
回答2:
You can easily find the hours between two date using:
select (end_date - start_date) * 24 from dual;
If your column is of type timestamp then use the following:
SELECT
EXTRACT(DAY FROM DIFF) * 24 +
EXTRACT(HOUR FROM DIFF) +
ROUND(EXTRACT(MINUTE FROM DIFF) / 60, 2) +
ROUND(EXTRACT(SECOND FROM DIFF) / 3600, 2) TOTAL_HOURS
FROM
(SELECT END_TIMESTAMP - START_TIMESTAMP AS DIFF
FROM DUAL)
-- or --
select (CAST(END_TIMESTAMP AS DATE)- CAST(START_TIMESTAMP AS DATE) ) * 24 from dual;
Cheers!!
回答3:
Well, Your LINE_STOP_TIME and LINE_START_TIME are character strings, not dates, so you cannot extract date info from them. Remove the TO_CHAR from the inline SELECT and it should be ok.
来源:https://stackoverflow.com/questions/58947840/ora-30076-invalid-extract-field-for-extract-source