× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Peter Dow wrote:
I'm trying for an SQL statement that will identify invalid
dates in a file that stores dates as 3 separate fields,
year, month and day. Something like:

SELECT DCTR#,DBRDTY,DBRDTM,DBRDTD
,case when date(digits(dbrdty) || '-' ||
digits(dbrdtm) || '-' ||
digits(dbrdtd)) is null
then 'ER'
else 'OK'
end
FROM QTEMP/T_GPPDCTR

Using the above statement, the invalid dates are displayed
as '++', the valid dates as 'OK'. If I try

SELECT DCTR#,DBRDTY,DBRDTM,DBRDTD
,case when date(digits(dbrdty) || '-' ||
digits(dbrdtm) || '-' ||
digits(dbrdtd)) = '++'
then 'ER'
else 'OK'
end
FROM QTEMP/T_GPPDCTR

I get "Comparison operator = operands not compatible.". The
manual is less than forthcoming about what is returned when
the argument is not a valid date.

If the expression for the character string as the operand of the DATE() scalar is not a valid date, then the result of the function will be a /data mapping error/. The value of an invalid expression such as the character string literal '2009-44-55' as a DATE() is not calculable, and would effect a data mapping error; in the STRSQL report writer, appears as a string of plus symbols. An incalculable value is also not capable of being utilized in a comparison [e.g. in a predicate for a WHEN], but instead of a data mapping error alone, when attempting to perform a comparison where the expression effects a data mapping error in the run-time evaluation, that will cause the query to terminate with a "select or omit error".

In the given failing scenario, the error stating there are incompatible operands is correct because the literal string '++' is not a /date data type/; i.e. the SQL wants to implicitly cast the string '++' to a date data type to then use to compare with the DATE(expression). Of course a character string which denotes a valid date is also not much of a /date data type/, but by implicit cast of such a literal, the character string as date value is the manner to input a human-readable date.

The definition for a UDF named vfyYYYMMDD to return either the valid date or the NULL value for an invalid date is given here [note that the "<>" does not appear in the MOD() for 100]:
http://www.ibm.com/developerworks/forums/thread.jspa?threadID=166849

The use of that UDF for the given scenario could be:
qgpl.vfyYYYYMMDD(cast(digits(dbrdty)
||digits(dbrdtm)
||digits(dbrdtd) as char(8)) )

However a more direct interpretation of the requirement as stated in the quoted text can be achieved similarly, either in a like-UDF or just inline to the query as here:

<code>

SELECT
DCTR#,DBRDTY,DBRDTM,DBRDTD
,case
when
DBRDTY between 0001 AND 9999
and ( /* month with full 31 days */
( DBRDTM IN (01, 03, 05, 07, 08, 10, 12)
and DBRDTD between 01 AND 31
)
or /* month with only 30 days */
( DBRDTM IN (04, 06, 09, 11)
and DBRDTD between 01 AND 30
)
or /* month with 28 days min. */
( DBRDTM = 02
and DBRDTD between 01 AND 28
)
or /* month with 29 days; leap */
( DBRDTM = 02
and DBRDTD = 29
and ( MOD(DBRDTY, 4) = 0
and ( MOD(DBRDTY, 100) <> 0
or MOD(DBRDTY, 400) = 0
)
)
)
)
then 'OK'
else 'ER'
end
FROM QTEMP/T_GPPDCTR

</code>

Regards, Chuck

As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.