|
Hi Elvis,I came to pretty much the same conclusion. However, rather than have a completely different procedure to handle the null case, I tried a prototype like this:
d AccountingMonth... d pi 10i 0 d amDate d options(*nopass)
d amDateNull 5i 0 options(*nopass) d amResultNull 5i 0 options(*nopass)I realize you're a C programmer, but the idea here is that I can then check a built-in function, %parms, which returns the number of parameters actually passed, to see if the parameter was actually passed. Unfortunately, it appears that SQL is one of those programs that the RPGLE manual mentions that does not pass a minimal operational descriptor, so %parms is unreliable; in fact, it is apparently always -1.
Another interesting thing I've noticed here is that although my service program is compiled with activation group *CALLER, the static variables I have defined are not static, i.e. they're reinitialized for every record returned by the SELECT statement. The SCRATCHPAD parameter on the CREATE FUNCTION statement says it's only allowed for Java programs; so how does an RPGLE program get some static storage?
It looks like I'll have to have a completely separate procedure in my service program to handle the null case, and I'll have to take the performance hit because of the lack of static storage.
*Peter Dow* / Dow Software Services, Inc. 909 793-9050 pdow@xxxxxxxxxxxxxxx <mailto:pdow@xxxxxxxxxxxxxxx> / Elvis Budimlic wrote:
Peter, bear with me as this is going to be a long post, but it should resolve your issue (I hope). My bad on suggesting that test without testing it myself. Reason you're getting the error with this is because it's looking for column named NULL inSYSIBM1 and that of course does not exist. Better test would be this:CREATE TABLE UTLIB/T1 (F1 DATE ); INSERT INTO UTLIB/T1 VALUES(NULL); SELECT ACCTGMONTH(F1) from UTLIB/T1; As you see I've created a table with a date field and then inserted a single NULL field in it. This is just so we can test NULL input to your UDF. I have also created a dummy UDF that sort of does what you're doing in yours. I code in C so my sample is also in C but you should be able to follow it as it's bare bones. Here is the sample function:int ACCTGMONTH( char * in, /* first parm */short * inNull, /* null indicator array */ short * outNull /* output null indicator */) { *outNull = 0; /* never NULL */if (inNull[0] == -1) /* if NULL passed in */ return -1; /* output negative one */ else /* if real value passed */ return 1; /* output positive one */ } I usually don't code with GENERAL WITH NULLS parameter style, but it is relatively straight forward. We have one input variable, so our inNull null indicator array of 2 byte binaries only has one element. I check if it's null by comparing it against negative 1. I don't have any logic for the output value but rather just output -1 if NULL was passed in and 1 if incoming argument was non-NULL. I don't code in RPG so I can't tell you if your function declaration is valid or not, but that's likely where the problem is. As I suspected, empty parenthesis are treated as a separate UDF (no arguments hence different signature) so I get "not found" error when runningit like that. To handle this case, I suggest you create another function in the sameservice program that handles this case and then register a separate UDF. That way you can reuse the code base already in your SRVPGM. Good luck. Elvis -----Original Message----- Subject: Re: Specify null parameter for SQL UDF Hi Elvis, I tried it and got "Column NULL not in specified tables."Another wrapper would work, but then what's the point of "CALLED ON NULL INPUT"? There should be a way to use it...shouldn't there?* Peter Dow* / Dow Software Services, Inc. 909 793-9050 pdow@xxxxxxxxxxxxxxx <mailto:pdow@xxxxxxxxxxxxxxx> / Elvis Budimlic wrote:I think your UDF syntax is fine, especially being that you did specify CALLED ON NULL INPUT. Perhaps empty parenthesis are not treated as NULL input?Test it with: SELECT ACCTGMONTH(NULL) FROM SYSIBM/SYSDUMMY1and verify if that's the case or not. If it is, you'll have to create another wrapper UDF that takes noparametersand perhaps maps to the original one. Elvis -----Original Message----- Subject: Specify null parameter for SQL UDF Hi Everyone,How do I call a UDF with a null parameter? I have a UDF created to return the accounting month for a given date (the only parameter), but if no parameter is given, it will return the current accounting month.It works fine when I pass it a date, e.g. SELECT ACCTGMONTH(CURRENT_DATE) FROM ANYFILE but complains (says it cannot find ACCTGMONTH) if I use it like this: SELECT ACCTGMONTH() FROM ANYFILEI understand that it identifies a UDF based on the name and the input parameter types, but I don't understand how to tell it a particular parameter may be optional.I created it with the following: create function UTLIB/ACCTGMONTH (date) returns integerlanguage RPGLE parameter style GENERAL WITH NULLS not deterministic no SQL called on null input no external action external name 'UTLIB/SVCBUS(ACCTGMONTH)'ACCTGMONTH is a procedure within a service program, with prototype like this:d AcctgMonth... d pr 10i 0 d amDate d const d amDateNull 10i 0 d amResultNull 10i 0*Peter Dow* / Dow Software Services, Inc. 909 793-9050 pdow@xxxxxxxxxxxxxxx <mailto:pdow@xxxxxxxxxxxxxxx>
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.