|
>> First off, why the Select Distinct? To dispose of the blanks returned by the UDF. Every UDF must return something. I looked at the manual and you cannot return nothing so I will tell it to return a one byte char field for each call . Cannot return a NULL so it would know that there is only one possibility. Be nice if IBM added that. If I have it correctly, the operating system(SQL Runtime) is going to read a record from data base, Build the string in the WRITEIFS, call the UDF and then back to get another record same as any other SELECT so if you did not put the DISTINCT in I would get 1.5 million blanks returned if processing a file with 1.5 million records just as if I was using my AS400DATE UDF but I would get back 1.5 million date data types. >> Note the use of the MAX function. You know Charles, you have got it. If I use MAX instead of DISTINCT, I don't have any of the problems I was thinking about. Each time it runs the UDF, it returns a blank, compares it to the previous value and does nothing because they are the same. That's it. Thank you very much. >> I'd do the headers like so >> Set dummyVar = WriteIFS( stringToWrite ) You are forgetting that you must have a SELECT statement. There is only one WRITEIFS issued for the whole 1.5 million records so it has to know where the get the data from just like any other SELECT. The set only works for, I think, for UDF that just do one thing like Opening the IFS. I haven't tested it yet so I don't know if it even works. I can use a SET for OPENIFS because the manual shows an example of a function SET :VALUEX = SUBSTR(:VALUEY,1,1) so Set :DummyField = OPENIFS(:FileName) will work. You know, it just occurs to me that it doesn't really make any sense to use SET on some and EXECUTE IMMEDIATE on others. Might as well just have one function that receives the string and does an EXECUTE IMMEDIATE. Again I would like to emphasize that that I am not going to be reading the records into the HLL. The HLL is there only to build and execute the SQL String. All the work occurs in the SQL Statement itself. This seems to be a point of a lot of confusion. The execution in the HLL is: OPEN WRITE Header1 WRITE Header2 WRITE 1.5 million records CLOSE No loops. Just these 5 statements plus what is needed to build the string to execute. I see the high level code as just being: BuildFieldTable(FileNametoCopy); ExecuteSQLString(BuildOpenString('/Home/YourDirectory/YourFile.txt')); ExecuteSQLString(BuildFirstHeader()); ExecuteSQLString(BuildSecondHeader()); ExecuteSQLString(BuildCopyString()); ExecuteSQLString(BuildCloseString()); ReleaseFieldTable(); That should be it. You know Rich, it just occurred to me. You don't even need the field table build. Simply have a table: TableName TableLibrary BuildHeaderOneSQLString BuildHeaderTwoSQLString CopyRecordsSQLString By rules of normalization, I would normalize to two tables: Unique TableName TableLibrary TransmitFileName K TableName K TableLibrary Unique TableName TableLibrary TypeOfString SQL String K TableName K TableLibrary K TypeOfString Now, if you realize you need to add another type of record to the FTP file, just add another SQL string type and program works the same. You could just build the statements in STRSQL or OPS NAV and paste them in. If you need to add a field, just edit the SQL string. The only statements you would need is for the WRITEIFS. You could still build the string dynamically but is it worth it? "Make everything as simple as possible, but not simpler." Albert Einstein So at this point, we have reduced the code down to a few dozen lines of code Ok, so know the high level code is just: Chain (FileNameToCopy:LibraryName) FileNameHeader; ExecuteSQLStatement(BuildOpenString(TransmitFileName)); Setll (FileNameToCopy:LibraryName) FileNameSQLStatements; DoU 0 = 1; Read FileNameSQLStatements; If %EOF or FileNameChanged; Exit; EndIf; ExecuteSQLString(SQLString); EndDo; ExecuteSQLString(BuildCloseString()); >> stm = 'values Select MAX(WriteIFS(' + wDataFormatString + ') from ' + >> wInputFileName + ') into ?' >> /exec SQL prepare s from :stm This is exactly what I am doing with the EXECUTE IMMEDIATE. I just don't have to bother with parameter markers and you cannot use parameter markers with EXECUTE IMMEDIATE. Manual says to use EXECUTE IMMEDIATE if the string is different each time and it would be. The wData FormatString iand wInputFileName is different each time it is executed.
As an Amazon Associate we earn from qualifying purchases.
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.