Joined: 08 Oct 2004 Posts: 274 Topics: 52 Location: California
Posted: Wed Mar 22, 2006 5:08 pm Post subject: DB2 Function written in COBOL Zos
I need to write function in COBOL that will receive a value and return a different value. Does anyone have an example of a simple procedure/COBOL program similar to my requirements? _________________ Thanks,
NASCAR9
Posted: Fri Jan 02, 2009 2:54 pm Post subject: UDFs in ZOS
I was wondering if anyone has anything new to add to this thread? I have a working SP, and a UDF created on it, but it doesn't return anything when invoked through a function call, while the SP does return stuff. There is no real SQL executed in the SP, just some string manipulation, and the UDF response is zero bytes long. For example, when the SP is given an input of '100', it returns ' 00100'; but when invoked as a UDF by issuing "SELECT SANDBOX.PARTS2L('100') FROM SYSIBM.SYSDUMMY1", no output is returned.
Any help will be greatly appreciated!
This seems to be an area where the DB2 manuals are especially weak in their attempt to provide solutions! _________________ Alan Gredell
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
Posted: Fri Jan 02, 2009 3:49 pm Post subject: Re: UDFs in ZOS
agredell wrote:
For example, when the SP is given an input of '100', it returns ' 00100'; but when invoked as a UDF by issuing "SELECT SANDBOX.PARTS2L('100') FROM SYSIBM.SYSDUMMY1", no output is returned.
agredell,
SYSIBM.SYSDUMMY1 has only 1 column named IBMREQD and you are not selecting it. If your intention is to get a character value for a numeric value ,you should use the function DIGITS.
Check this link for a detailed explanation on DIGITS function
Joined: 08 Aug 2007 Posts: 291 Topics: 2 Location: Chicago
Posted: Fri Jan 02, 2009 4:22 pm Post subject:
What does this mean?
Quote:
I have a working SP, and a UDF created on it
Are you saying that the UDF CALLS the stored proc? If that's the case, is the CALL to the stored proc qualified, or unqualified? Post the DDL so we can see what's going on.
Kolusu, I think I understand what you mean, and it will be possible for me to test this UDF using a value selected from a real table.
jsharon, I was using the statement in the reply to the original post, that there is no significant difference between a SP and a UDF; I took that to mean that I could define a UDF using the EXTERNAL_NAME of the SP, and we did get it to run that way, it just wouldn't return any results.
One thing that occurred to us is that the SP was coded with an INOUT field, where both the input and the output are using the same Linkage Section variable. The DBA who is responsible for the original SP is trying to add a second, output variable to the Linkage Section of the COBOL program. That might help, as might Kolusu's suggestion.
Thanks, I will keep you posted! _________________ Alan Gredell
The changes we made worked! Kolusu, it appears not to matter that the SYSDUMMY1 table definition is not equal to the field or fields in question; for example, the following query:
select sandbox.parts2x('100') from sysibm.sysdummy1
worked perfectly, returning the value '00100', which is what we needed.
I believe that there are some differences regarding what will work in an SP and what will work in a UDF, but they are largely the same.
A UDF will require two fields (at a minimum), one for input, the other for output. They appear to require variable length fields to be used, though I wouldn't swear to that one; at any rate, it's working!
Thanks for helping me think this through!!! _________________ Alan Gredell
Joined: 08 Aug 2007 Posts: 291 Topics: 2 Location: Chicago
Posted: Thu Jan 08, 2009 1:35 pm Post subject:
A couple things to point out. First, regarding SYSIBM.SYSDUMMY1, the table is defined with 1 column and populated with 1 row. The 1 row is the feature that makes the table valuable. You could select CURRENT TIMESTAMP from any table, but it will be returned once for every row on the table. Issuing the select to SYSIBM.SYDUMMY1 will return 1, and only 1 row. In your case, you're selecting the results of a UDF.
Second, regarding the similarities and differences between SP's and UDF's, they are similar from the external coding perspective. You pass them parms, and they do some work. To the DB they are very different. SP's are explicitly called using a CALL statement, and UDF's are implicitely invoked when the UDF name is encountered in SQL statements. UDF's do not require input parameters. The parameter types defined in the UDF must be compatible with the parameters defined in the external program. I hope you haven't defined the UDF and SP to both call the same COBOL pgm. If you need to execute the same program, define the SP to call the COBOL program, and issue a CALL to the SP from the UDF.
At this point, I'm curious what changes you made to resolve your issues.
I have used SYSIBM.SYSDUMMY1 for years in cases where I had a literal that needed a function of any kind applied. Normally, I will expect this UDF to reference a column in a table, rather than a literal, and therefore will reference that table instead of SYSIBM.SYSDUMMY1.
I guess the second paragraph of your post is stating that there is a difference between a UDF and the program that is excecuted due to the invoking of the function. That's a good point, it helps to keep them separated.
As far as what we had to do to make the SP work as a UDF, I didn't actually do it, but the SP was coded with a parameter type of INOUT; we could not get the UDF to work that way, so we modified the linkage section to have separate input and output variables. Also, the SP was capable of handling a fixed length character field, but we had to make it a VARCHAR to get the UDF to work.
Here is a synopsis of our requirement: Our company has two (maybe more, but two is one too many!) version of many, maybe all, product identifiers. I'm talking about what the user calls a product. The users that create the product names have put some "intelligence" into the number, but only in some cases. Both versions of the product number have a pattern XX99999XXX. There are numerous rules around the values allowed for the X's, but the first two characters are permitted to be blank, as are the last 3. Then, the middle 5 have just numerics. But the "official" (we call it the long) part number might have leading zeros (and this is true even if the first two characters are NOT blanks). Some sample long part numbers are: < 00100 >, <DL01234M05>, <DR09451 15>, <A 00001N01> (Note that the <> are delimiters for clarity)
Our sales force consist of independent agents; and the programmers that built their system were an independent bunch, too! They analyzed the data in these fields and figured that they could save keystrokes for the sales force by shortening the part number by eliminated leading spaces and leading zeros in the numeric portion of the number. So, the short versions of the above numbers would be (still always 10 characters!): <100 >, <DL1234M05 >, <DR9451 15 >, <A1N01 >.
Finally, a new application started out by using the wrong table to verify part numbers. The table they used stored the short number, but was an incomplete list. The correct table with all current values only stores the long number. Hence, we decided that a UDF would help us go either way.
Long story short (oops, too late! ), we got both of them working today. It's not the smartest thing to do, but my company has a habit of not always doing the smart thing (or else we wouldn't have two versions of part numbers!!!)
Thanks for helping me think this through, guys! _________________ Alan Gredell
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum