我无法弄清楚为什么我收到一个无效月份错误。我可以使用to_date返回每个字段而没有错误但是当我添加之间的过滤器时它会爆炸。我正在使用Oracle。奇怪的是并不是每一个记录炸弹都是
SELECT *
FROM timedetail_dates
WHERE empnum = '501331134'
AND (TO_DATE ('10/14/2016 04:00', 'mm/dd/yyyy hh24:mi')
BETWEEN TO_DATE (timein_date, 'mm/dd/yyyy hh24:mi')
AND TO_DATE (timeout_date, 'mm/dd/yyyy hh24:mi')
)
AND tsdate BETWEEN '09-oct-2016' AND '22-oct-2016'
AND timedetail_dates.DURATION > 0;
答案 0 :(得分:1)
在TO_DATE的BETWEEN条款中包含日期,以及
Stud Name
AA
BB
CC
DD
EE
FF
GG
HH
II
JJ
KK
LL
MM
NN
OO
PP
QQ
RR
SS
TT
UU
VV
此外,如果您的tsdate列不是日期类型,您还需要将其包装在您将数据存储在列中的格式中。
答案 1 :(得分:0)
It sounds like you have an invalid date in your table. You receive this error when the string being parsed is incorrect. Here's an example query that produces it.
SELECT TO_DATE('22-10-2016 05:31', 'mm/dd/yyyy hh24:mi') FROM DUAL;
As a_horse_with_no_name implies, using VARCHAR
(or VARCHAR2
or any text type) is usually a poor data type for temporal data. This is part of the reason why: it's difficult to prevent invalid data from getting into the database.
You need to prevent bad data from getting into the database to start with:
TIMESTAMP
(possibly WITH TIME ZONE
) or DATE
.To find the offending row, try this. First create a function:
CREATE OR REPLACE FUNCTION DATETIME_IS_VALID_FOR_FORMAT(
TEXT_DATETIME VARCHAR2,
DATETIME_FORMAT VARCHAR2
)
RETURN VARCHAR2
IS
DUMMYVAR DATE;
BEGIN
-- The assignment is only here to get the function to compile
DUMMYVAR := TO_DATE(TEXT_DATETIME, DATETIME_FORMAT);
RETURN 'TRUE';
EXCEPTION
WHEN OTHERS THEN
RETURN 'FALSE';
END;
/
Now SELECT
the rows where this is 'FALSE'
:
SELECT *
FROM timedetail_dates
WHERE
DATETIME_IS_VALID_FOR_FORMAT(timein_date, 'mm/dd/yyyy hh24:mi') != 'TRUE' OR
DATETIME_IS_VALID_FOR_FORMAT(timeout_date, 'mm/dd/yyyy hh24:mi') != 'TRUE'
If you can't create functions because of low privileges on the database, you'll have to leverage DBMS_OUTPUT
instead. Replace ID_COLUMN
in the anonymous block below, and you can use it to find the bad rows:
DECLARE
FUNCTION DATETIME_IS_VALID_FOR_FORMAT(
TEXT_DATETIME VARCHAR2,
DATETIME_FORMAT VARCHAR2
)
RETURN VARCHAR2
IS
DUMMYVAR DATE;
BEGIN
-- The assignment is only here to get the function to compile
DUMMYVAR := TO_DATE(TEXT_DATETIME, DATETIME_FORMAT);
RETURN 'TRUE';
EXCEPTION
WHEN OTHERS THEN
RETURN 'FALSE';
END;
BEGIN
FOR T_ROW IN (SELECT * FROM timedetail_dates) LOOP
IF (
DATETIME_IS_VALID_FOR_FORMAT(T_ROW.TIMEIN_DATE, 'mm/dd/yyyy hh24:mi') != 'TRUE' OR
DATETIME_IS_VALID_FOR_FORMAT(T_ROW.TIMEOUT_DATE, 'mm/dd/yyyy hh24:mi') != 'TRUE'
) THEN
-- Replace ID_COLUMN with your actual primary key
DBMS_OUTPUT.PUT_LINE('Bad row: '||T_ROW.ID_COLUMN);
END IF;
END LOOP;
END;
/
Note that you'll probably have to do some preparation to make your client start capturing the output from DBMS_OUTPUT.PUT_LINE
. (This is client dependent, but you have to turn it on in both SQL*Plus and Oracle SQL Developer.) Also note that none of the output will show up until the block completes.