× 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.



On 07 Mar 2013 12:22, Smith, Mike wrote:
I am trying to convert a static SQL statement to allow for some
flexibility and I'm having trouble with the dates.

This is the original SQL statement.

declare db2curs cursor for
SELECT
TE1DPT, TEMEMP, TEMNAM, TEMBDT, TEMHDT, TEMRDT
, integer(floor(:currentdate - getdatesql(TEMBDT)) / 10000) as age
, integer(floor(:currentdate - getdatesql(TEMHDT)) / 10000) as YOS
FROM tremp
, trei1
WHERE TEMEMP = TE1EMP
and TEMEES = 'FR'
Order by age desc
;
Currentdate = %date(daterun:*USA0) ;
Getdatesql is a udf that converts an 8 digit date to a date field.

The problem I'm having is with current date.

Here is where I'm at now.
Select ;
When FPEMP = 'F' ;
Sts = 'TEEMES = ' + Q + 'FR' + Q;
When FPEMP = 'P' ;
Sts = 'TEEMES = ' + Q + 'PT' + Q;
EndSl ;

sqlstring =
'select TE1DPT,TEMEMP,TEMNAM,TEMBDT,TEMHDT,TEMRDT,' +
'integer(floor(' + currentdate + ' - getdatesql(TEMBDT)) / ' +
'10000) as age, ' +
'integer(floor(' + currentdate + ' - getdatesql(TEMHDT)) / ' +
'10000) as YOS from TREMP,TREI1 ' +
'WHERE TEMEMP = TE1EMP and ' + STS + 'ORDER BY AGE,DESC';

Exec sql
Prepare SQLStatement from :SQLSTRING;
Exec Sql
Declare db2curs cursor for SQLSTATEMENT ;

So currentdate which is a date, I can't get to be part of sqlstring
I feel like I'm missing the obvious here, but I can't get my brain
around the solution.

If fully dynamic is desirable over use of parameter markers, then I would probably do the following:

Instead of building the entire predicate into the variable STS, I would leave the predicate visible in the formation\concatenation of the SQL statement; concatenating only the operand. So first setting STS:

Select ;
When FPEMP = 'F' ;
Sts = Q + 'FR' + Q ;
When FPEMP = 'P' ;
Sts = Q + 'PT' + Q ;
EndSl ;

As Scott noted in the first reply to the thread, and apparently what has already been done... the Currentdate as a Date data type variable must be cast to character to properly concatenate in the string. And as a SQL character constant embedded in a string, that value would also have to have apostrophes added. So any one of the following, where the first must be understood contextually to be a date literal, and the others explicitly state that the string is to be recognized as a date:

quotedDate = Q + %char(currentdate:*ISO) + Q ;

quotedDate = 'Date' + Q + %char(currentdate:*ISO) + Q ;

quotedDate = 'DATE(' + Q + %char(currentdate:*ISO) + Q + ')' ;

With that, I might do the following:

sqlstring =
' select' +
' TE1DPT,TEMEMP,TEMNAM,TEMBDT,TEMHDT,TEMRDT' +
' , integer(floor(' + quoteddate + ' - getdatesql(TEMBDT)) /' +
'10000) as age' +
' , integer(floor(' + quoteddate + ' - getdatesql(TEMHDT)) /' +
'10000) as YOS'
' from TREMP' +
' inner join TREI1' +
' on TEMEMP = TE1EMP'
' where TEMEES =' + STS +
' order by age desc'
;

However I would probably instead of using fully dynamic, make the SQL much simpler and use parameter markers for the variables that had their values just as easily established in the host language code. Michael had shown that, but only offering an example of the variable STS used in the WHERE clause, not of the other variable(s). So with parameter markers:

The variable STS need only be a 2-byte character to match the column TEMEES data type and length, and no more worry about adding the apostrophes:

Select ;
When FPEMP = 'F' ;
Sts = 'FR' ;
When FPEMP = 'P' ;
Sts = 'PT' ;
EndSl ;

The variable Currentdate can remain a date, keeping the original eval:

Currentdate = %date(daterun:*USA0) ;

Or the variable Currentdate could be a character string, but again no worry about adding apostrophes, using the following eval:

Currentdate = %char(%date(daterun:*USA0):*ISO) ;

With that, I might do the following with parameter markers; using the CAST to let the SQL know into what desired type is the host language variable to be cast:

sqlstring =
' select' +
' TE1DPT,TEMEMP,TEMNAM,TEMBDT,TEMHDT,TEMRDT' +
' , integer(floor( cast( ? as date) - getdatesql(TEMBDT)) /' +
'10000) as age' +
' , integer(floor( cast( ? as date) - getdatesql(TEMHDT)) /' +
'10000) as YOS'
' from TREMP' +
' inner join TREI1' +
' on TEMEMP = TE1EMP'
' where TEMEES = ?' +
' order by age desc'
;
Exec sql
Prepare SQLStatement from :SQLSTRING;
// check SQLCODE here
Exec Sql
Declare db2curs cursor for SQLSTATEMENT ;
Exec Sql
open C2 using :currentdate, :currentdate, :sts ;

FWiW: The ORDER BY is on an expression instead of a column which will [¿always?] require a temporary result for collation\sorting. Since that expression is derived from an effective date [the column TEMBDT, subtracted from a constant value], if that column is capable of being properly ordered [e.g. in the form YYYYMMDD] then that column likely could be sorted ASCending to effect the same result sequence; i.e. the oldest date will always yield the largest value for the expression and the newest date will always yield the smallest value for the expression.


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.