On 12-Oct-2016 09:28 -0500, Bill Reed wrote:
Yes, OELIB is the service program's library.
(The following is a simplified example, but with the same results.
The actual function, procedure, etc., is obviously more involved.)
This example takes the name of a printer device (10 chars) and
returns a 30-character description from a table.
Function name: fnGetPrintDsc
Procedure name: prGetPrintDsc2 in service program XX0504V in library
OELIB.
Function generated thus:
CREATE OR REPLACE FUNCTION OELIB/FNGETPRINTDSC (
PRINTER VARCHAR(10) )
RETURNS CHAR(30)
LANGUAGE RPGLE
SPECIFIC OELIB/FNGETPRINTDSC
NOT DETERMINISTIC
NO SQL
CALLED ON NULL INPUT
EXTERNAL NAME 'OELIB/XX0504V(PRGETPRINTDSC2)'
PARAMETER STYLE GENERAL ;
RPG code for the procedure: (which calls another procedure but done
this way to allow the Varying keyword)
P prGetPrintDsc2 B Export
D prGetPrintDsc2 PI 30a
D pvPrintId 10a Const Varying
/free
Return prGetPrintDsc(pvPrintId); // another procedure
// (note absence of '2' on end) which
// returns 30 character text
/end-free
P prGetPrintDsc2 E
SQL statement in the Excel connection properties:
select OELIB.FNGETPRINTDSC('PRT03') from SYSIBM.SYSDUMMY1
This will not even let me save and close the connection properties
window without the "service program not found" error. But the same
select statement pasted into Run SQL scripts returns the text for
PRT03 just fine.
I realize I could CAST the input as character instead of using
Varying, but at least I know the above works in the IBM i context.
Levels:
IBM i: 7.1
Excel 2010
I suppose DROP FUNCTION followed by a new CREATE FUNCTION of the
original SQL ROUTINE is moot; i.e. the above expresses an actual
re-create example, from scratch?
With both the above and the Service Program information given in
another reply, I see nothing specifically wrong. Perhaps try to get a
spooled debug joblog of the server job that services the failing request
to see if there is anything peculiar in the joblog other than the -204
[msg SQL0204]; also get a DSPJOB of that job, which should show the file
QASQRESL as open, though for not finding the routine, so I expect no RRN
position to show in the Open Files information.
FWiW, a variation of the following query is what I have sometimes
used to perform a quick sanity check on some definitional details for a
FUNCTION routine that has a particular external procedure name expected
for a specific library name. The query would expose [by close/careful
review] if there are possibly multiple definitions for the FUNCTION due
to either possible overloading or incorrect character-casing on the
procedure name [which, as I recall, is a common origin for the noted
error]; my /shortened/ values may not be appropriate quite generally,
but they work for me, mostly, until I have to bump them up a litle ;-)
SELECT varchar(routine_schema, 10) as lib
, varchar(routine_name , 18) as name
, varchar(specific_schema, 10) as speclib
, varchar(specific_name , 18) as specname
, varchar(external_name, 36) as extname
, varchar(char(routine_created), 16) as crt
, routine_body as body, EXTERNAL_LANGUAGE as lang
, parameter_style as style, is_deterministic as det
, varchar(sql_path, 36) as path
, number_of_results as rtn
, out_parms as out, in_parms as in
, varchar( SOURCE_SPECIFIC_SCHEMA, 10) as srclib
, varchar( SOURCE_SPECIFIC_NAME , 18) as srcnam
FROM table
( select *
from qsys2.sysroutine
where ROUTINE_TYPE='FUNCTION' ) as n
WHERE ( routine_schema= 'OELIB'
and upper(routine_name) like '%FNGETPRINTDSC%' )
or ( specific_schema='OELIB'
and upper(specific_name) like '%FNGETPRINTDSC%' )
or upper(external_name) like upper('%prGetPrintDsc2%')
ORDER BY name, lib
If nothing conspicuous found with that, then I would review output
from DSPDBR QSYS2/SYSROUTINE to ensure that the file QASQRESL in QSYS2
is shown; again with DSPDBR QSYS2/SYSROUTINE MBR(SYSROUTINE). Then I
would review the definitions of both of those files to ensure there is
just one member and that the access path is valid for the QASQRESL file
as INDEX. If nothing still, then probably I would make a backup of the
files SYSROUTINE and SYSPARMS along with any LF or INDEX created over
them, using ACCPTH(*YES), and then I would RGZPFM QSYS2/SYSROUTINE
ALWCANCEL(*NO).
As an Amazon Associate we earn from qualifying purchases.