Hi, I attempting to use "create call" to run a program with a set of parameters in a temp table. When I configure an "OUTPUT" parameter, I get an error stating: "Record paramTable not available for dynamic output parameter. (10088)" I first tried this by passing a table handle to a method and then creating a dynamic query. When this failed, I created a static temp-table in the class, and had the same problem. Does anyone know if there is any reason why this might not work in 10.2b008?
I followed the examples on this page: documentation.progress.com/.../index.html
This is absolutely the problem … I’ve run into it and it’s a Royal PITA to work around.
There are a couple of approaches you can use.
1) Create a dynamic temp-table with one field per parameter (and one for the return value). Make sure you FIND it and keep it in scope before and after the INVOKE() call. This works pretty well except when you have parameters with variable-extent arrays.
2) In that case you end up defining a bunch of local variables in a single internal procedure or method and use what you need. Things get to look ugly fast but it works for pretty much everything. I used a bunch of case statements with include files
If you’re on 11.6.3+ you can see the approach I ended up taking for classes with the Progress.Lang.ParameterList object – which suffers from the same challenge. In 11.7.0+ there’ll be a procedure-based equivalent. The former is in the Execute() method in OpenEdge.Web.DataObject.ClassOperationHandler and the latter in OpenEdge.Web.DataObject.ProcedureOperationHandler. You can find both in the $DLC/src/netlib/OpenEdge.Net.pl procedure library.
It will help if you show some of the code involved, specially for the SET-PARAMETER() call.
This code, taken from the example works great:
define variable hCall as handle no-undo.
define variable outVal as character no-undo.
create call hCall.
/* Invoke hello.p non-persistently */hCall:call-name = "node.p"./* Sets CALL-TYPE to the default */hCall:call-type = procedure-call-type.hCall:num-parameters = 2.hCall:set-parameter(1, "CHARACTER", "INPUT", "HELLO WORLD").hCall:set-parameter(2, "CHARACTER", "OUTPUT", outVal).hCall:invoke.
message outVal view-as alert-box.
/* Clean up */delete object hCall.
This code, using a simple temp table for the parameters returns the error "Record paramTable not available for dynamic output parameter. (10088)." Please let me know if there is anything I need to change to make it work.
define temp-table paramTable no-undo field idx as integer field mode as character field typ as character field val as character.
create paramTable. assign paramTable.idx = 1 paramTable.mode = "INPUT" paramTable.typ = "character" paramTable.val = "HELLO WORLD". create paramTable. assign paramTable.idx = 2 paramTable.mode = "OUTPUT" paramTable.typ = "character" paramTable.val = "".
/* Invoke hello.p non-persistently */hCall:call-name = "node.p"./* Sets CALL-TYPE to the default */hCall:call-type = procedure-call-type.hCall:num-parameters = 2.
for each paramTable: message string(paramTable.idx) + ":" + paramTable.typ + ":" + paramTable.mode + ":" + paramTable.val. hCall:set-parameter(paramTable.idx,paramTable.typ, paramTable.mode, paramTable.val).
I understand what you are trying to achieve, but I can also understand a little bit why Progress throws the error.
When the call is invoked, the temp-table records are out of scope, which makes it perhaps difficult to populate them with the output?
I feel that might be the problem.
You are thinking in the line of "one row, one parameter" and you should think it as "one row, one invocation".
With that I mean that each table rows must/may have every calling parameter, as a column.
You have options, but the thing is that ABL needs to access the OUTPUT placeholder before, and after, the CALL.
That means that every row you are using as an OUTPUT needs to be AVAILABLE after the CALL, with your example is still possible with little changes, but: what if you have more than one OUTPUT?
In the later case you need to use a different TABLE for each OUTPUT so every one is AVAILABLE at the same time, or different columns of the same ROW.
In our framework we create a dynamic TEMP-TABLE with a column for each parameter of the invocation, whether it is an INPUT, OUTPUT or INPUT-OUTPUT, create a row, populate it, make the CALL, read the outputs, create another row, populate it, make the CALL, etc.
Thanks everyone for the responses, all were very helpful. I see the problem now, and wish there was a more elegant way to handle it. Too bad the call can't retain a reference to the output field. I will have to go the route for a dynamic temp table with a single row and then pull the data back out.