External stored procedure on IBM i - stored-procedures

I am trying to create an external stored procedure on an IBM i (V5R4), but I'm getting an error when I try to run it.
All I want to do is call an RPG program, without passing any parameters or worrying about returning any data. Sorry, I'm not an RPG programmer or an expert on IBM i, so I could be missing something very simple.
The SQL to create the procedure:
CREATE PROCEDURE SOMELIB.SOMEPROC ( )
LANGUAGE RPGLE
NOT DETERMINISTIC
NO SQL
EXTERNAL NAME 'OTHERLIB/SOMERG'
PARAMETER STYLE GENERAL;
The error I get when executing CALL SOMELIB.SOMEPROC() is:
SQL State: 38501
Vendor Code: -443
Message: [CEE9901] Application error. RNX1216 unmonitored by BB1002RG at statement 2100000001, instruction X'0000'. Cause . . . . . : The application ended abnormally because an exception occurred and was not handled. The name of the program to which the unhandled exception is sent is SOMERG SOMERG . The program was stopped at the high-level language statement number(s) at the time the message was sent. If more than one statement number is shown, the program is an optimized ILE program. Optimization does not allow a single statement number to be determined. If *N is shown as a value, it means the real value was not available. Recovery . . . : See the low level messages previously listed to locate the cause of the exception. Correct any errors, and then try the request again.

Your procedure is calling the RPG program without the library list set. You can do one of two things:
1) Change the F-spec in the RPG program to qualify the library using the EXTFILE keyword.
2) Call a CL program from the stored procedure that adds the appropriate library to the library list making sure to allow for the fact that the library may already be there from a prior call. Then have the CL program call the RPG program.

(a little bit more rude solution) Identify the user that starts the Stored Procedure. Change the jobdescription of that user to have the correct library list.
But in my experience is the CL program the most pragmatic solution too.

Assuming the file is in the same library as the program, add EXTFILE(variablename) and USROPN to the F-spec. Take the library name from the PSDS and construct the variablename value before you OPEN the file.
If the file and program are in different libraries, you might create a data area in the program library to hold the name of the data library. Retrieve the data area (using the PSDS) instead of using the PSDS (for the file library). If program and file aren't kept together, it can be a good idea to keep the data library name in an external object that can be changed rather than recompiling.
(Actually, I've rarely used data areas in the past ten years or so. Instead I create a user index. Each entry in the *USRIDX replaces a data area. The entries are keyed by a value that used to be a data area name. One object replaces many others and one procedure can manage all entries. One object to own and authorize reduces some system overhead.)

A suggestion to get rid of this trouble: make the user profile JOBD contains all libraries needed by the stored procedure.

Related

zOS: MODULE INCORPORATES VERSION 3 PROGRAM OBJECT FEATURES AND CANNOT BE SAVED IN LOAD MODULE FORMAT

I'm trying to do the linkage of a hello world in cobol, as in this tutorial, I can compile the program and get the new member in project.group.OBJ successfully, but when I link it with
LINK project.group.OBJ(Member) lib('cee.sceelked')
I get the following:
IEW2278I B352 INVOCATION PARAMETERS - TERM
IEW2606S 4B39 MODULE INCORPORATES VERSION 3 PROGRAM OBJECT FEATURES AND CANNOT
BE SAVED IN LOAD MODULE FORMAT.
IEW2008I 0F03 PROCESSING COMPLETED. RETURN CODE = 12.
I realized that in 4 (foreground) option, the link editor appears with an asterisk at the left: "7 *Binder/Link editor" which indicates "No packed data support".
Is the error because of that? What does it mean "No packed data support"? I can access that option with no problem.
Searching I found a link which indicates "An attempt is being made to save a module in a format that is incompatible with the features being used" But I don't know what they mean by the features being used. Is it related to the type of the dataset load in which is supposed to be put when linked? I am lost.
The load module format is very old. The last COBOL compiler from IBM that would generate code that could be bound as a load module is IBM Enterprise COBOL 4.2.x, which is scheduled for end of service on 30-Apr-2022. Even that compiler would generate code that could not be stored as a load module if you used certain compile options, i.e. DLL.
More recent versions of IBM Enterprise COBOL generate code which must be bound as a program object. A program object, while executable like a load module, is very different from a load module.
Load modules are stored in PDSs (Partitioned Data Sets). Program objects must be stored in PDSEs (Partitioned Data Sets Extended).
Ensure the SYSLMOD DD of your bind step (the project.group.LOAD dataset) is pointing to a PDSE. When you allocate it with ISPF 3.2 set the Data set name type to LIBRARY.

Does the order of hdf5 close matter?

I am implementing a HDF5 layer in an interpreted language with automatic reclamation facilities (garbage collect).
When a proxy to a HDF5 entity (H5File, H5Group, H5Dataset, H5Dataspace, H5Datatype, etc...) will be no longer referenced, it will be automatically reclaimed. With ephemeron like facility, I can arrange to be noticed and invoke the corresponding close function automagically (H5Fclose, H5Gclose, H5Dclose, etc...) in order to release the target resource.
By default, I have no control on the order of reclamation. However, if ever order of close counts, then I can arrange to keep a strong pointer on a parent proxy (for example the H5 File) from within any other entity. If order does not count, then I will avoid this useless complication.
So my questions:
Can I invoke H5Fclose(fid); before H5Gclose(gid); where previously gid=H5Gcreate(fid,'/foo',H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);?
Can I continue to operate on the group once I closed the containing file? For example, is it legal to call H5Fclose(fid); before gid2=H5Gcreate(gid,'bar',H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); in above example? If not, are there other entities concerned, or is it just file?
Doh, case of blindness, the documentation tells that close is delayed until all objects have been closed, so 1. order does not count and 2. is legal.
https://support.hdfgroup.org/HDF5/doc1.6/RM_H5F.html#File-Close
However, it may not work in every circumstances, so it's not recommended.
H5Fclose terminates access to an HDF5 file by flushing all data to storage and terminating access to the file through file_id.
If this is the last file identifier open for the file and no other access identifier is open (e.g., a dataset identifier, group identifier, or shared datatype identifier), the file will be fully closed and access will end.
Delayed close:
Note the following deviation from the above-described behavior. If H5Fclose is called for a file but one or more objects within the file remain open, those objects will remain accessible until they are individually closed. Thus, if the dataset data_sample is open when H5Fclose is called for the file containing it, data_sample will remain open and accessible (including writable) until it is explicitely closed. The file will be automatically closed once all objects in the file have been closed.
Be warned, however, that there are circumstances where it is not possible to delay closing a file. For example, an MPI-IO file close is a collective call; all of the processes that opened the file must close it collectively. The file cannot be closed at some time in the future by each process in an independent fashion. Another example is that an application using an AFS token-based file access privilage may destroy its AFS token after H5Fclose has returned successfully. This would make any future access to the file, or any object within it, illegal.
In such situations, applications must close all open objects in a file before calling H5Fclose. It is generally recommended to do so in all cases.

Creating a DTS package that uses a stored procedure

We're trying to make a DTS package where it'll launch a stored procedure and capture the contents in a flat file. This will have to run every night, and the new file should overwrite the existing file.
This wouldn't normally be a problem, as we just plug in the query and it runs, but this time everything was complicated enough that we chose to approach it with a stored procedure employing temporary tables. How can I go about using this in a DTS package? I tried going the normal route with the Wizard and then plugging in EXEC BlahBlah.dbo... It did not care for that:
The Statement could not be parsed. Additional information: Invalid object name '#DestinyDistHS'. (Microsoft SQL Server Native Client 10.0)
Can anyone guide me in the right direction here?
Thanks.
Is it an option to simply populate a non-temp table in your SP, call it and select from the non temp table when exporting?
This is only an issue if you have multiple simultaneous calls to the stored procedure. In this case you can't save to a single table.
If you do have multiple simultaneous calls then you might be able to:
Create a temp table to hold results
Use INSERT INTO #TempTable EXEC YourProc
SELECT FROM #TempTable
You might need to do this in a more forgiving command line tool (like SQLCMD). It's not as fussy about metadata.

How to abend job intentionally

Is it possible to abend your job intentionally through COBOL program.
suppose I have an Input file having Header,Detail and Trailer records. I will write a COBOL pgm which reads this file.If no Detail records are found in this file then I want to abend my job by giving some Abend Message and some Abend Code.Is it Possible?
Do you want to ABEND your program or just set a RETURN-CODE?
I suspect setting a RETURN-CODE, writing a message
and then terminating the program via a STOP RUN or GOBACK is all that
you really want to do. Causing an actual ABEND may not be necessary.
In an IBM batch environment, the RETURN-CODE set by your program becomes the
RC for the JCL job step the program was run under. This is typically what you
want to set and test for.
The RETURN-CODE is set by MOVEing a numeric value to it. For example:
DISPLAY 'No Detail Records found in file.'
MOVE 16 TO RETURN-CODE
GOBACK.
You may also issue a program dump from a program run under Language Environment (IBM
Mainframe option) using
the CEE3DMP--Generate dump
utility.
In older IBM Mainframe COBOL programs, you might see calls to the ILBOABN0 routine. This call
abended your program and issued a dump. This routine is now depreciated in favour of the
technique outlined above.
Finally, really old programs might have code in them to generate abends. This can be done in any number of ways, but division by zero was
often a favourite:
DIVIDE SOME-NUMBER BY ZERO GIVING SOME-NUMBER.
Works every time!
Personally, I recommend setting the RETURN-CODE over calling ILBOABN0 or data-exception tehcniques.
Note: The RETURN-CODE special-register is not part of the COBOL-85 standard. It is available as an IBM extention to the language. You may need to resort to a different mechanism if you are working in a non-IBM compatible environment.
see the following link on how to set the return code passed back to a JCL job step as well as force an Abened code.
http://www.tek-tips.com/viewthread.cfm?qid=1058302&page=22
First, you should check what is accepted by your own shop's/site's working standards. Most teams will already have an accepted way to deliberately abend a program for a 'logic' reason. One company I worked at has a very simple program called SYSABND2, which I believe is written in assembler, which is called just to abend the program.
That said, to ABEND (not just set return code), you should call module CEE3ABD (or previous version ILBOABN0, which is now deprecated).
For details, see:
https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.ceea300/clcdump.htm
http://publib.boulder.ibm.com/infocenter/zvm/v5r4/index.jsp?topic=/com.ibm.zos.r9.ceea400/ceea4150320.htm
One method for doing an abnormal end of run is to output a message to the user terminal or to the operator at a mainframe computer centre and possibly to a printer if necessary, all depending on the type of computer the program is to be run on. In cobol it is possible to use DISPLAY UPON .. and use an identifier for the terminal, operator console, or printer as defined in an entry in the SPECIAL-NAMES section of the ENVIRONMENT DIVISION. An example may be similar to this using the correct device names for your case
OPERATOR-CONSOLE IS OUT-OP2 in special-names with DISPLAY "RUN ERROR - NO DETAIL RECORDS, ABORTING" UPON OUT-OP2 and
DISPLAY "REPORT TO OPERATIONS MANAGER" UPON OUT-OP2 and STOP RUN. in procedure division.
A reference to the circumstance would need to be included in any job or macro and operating instructions.
Yes, it is possible to abend your job intentionally through COBOL program by simply calling one module which doesn't exist. It will give S806 abend code.

Commitment control error on iSeries procedure call

I have an intermittent problem when calling an iSeries stored procedure (consisting of various CL & RPG programs). The error is:-
Commitment definition *N not valid for open of QAOSSI12
Error occurred while opening file QAOSSI12.
As mentioned the problem does not always occur but occurs more when load testing the procedure.
I know the information is vague but any ideas appreciated!!
If this is error CPF4326, the message text gives the following possibilities:
Member QAOSSI12 was opened for commitment control when commitment definition *N was not active.
Uncommitted changes are pending for member QAOSSI12 for a commitment definition other than *N.
The calling program is using commitment definition *N which has a scope of *ACTGRP, while the program specified to open the file using ascope of *JOB.
Are these situations possibles in your case?
We've been getting CPF4326 and the solution that seems to be working is to add "transaction isolation=none" to our jdbc URL. We aren't trying to use transactions anyway, so there's no benefit to having them enabled. We're also suspicious that something in iBATIS is trying to rollback the transaction when there is an error, even though we don't do anything explicit as far as commitment control.
You can change COMMIT value at compile time to COMMIT(*NONE) then no commitment definition is created .
The Commit (COMMIT) command is used to complete the current transaction and to establish a new commitment boundary for the commitment definition associated with the program issuing the command.
You have to check also if your file in under Journal.

Resources