Yes, you are correct, I should have said to do the DESCRIBE "before the FETCH" meaning after the open.
Art S. Kagel, President and Principal Consultant
ASK Database Management Corp.
Original Message:
Sent: Thu November 20, 2025 02:35 AM
From: Sebastien FLAESCH
Subject: ESQL/C DESCRIBE OUTPUT after OPEN (with DECLARE CURSOR name) fails with -410
Art,
Just re-read you last comment where you write:
and must use PREPARE...DECLARE CURSOR...OPEN ... FETCH ... CLOSE paradigm in order to be able to DESCRIBE the prepared statement before executing it and fetching the data.
In fact the idea is to perform the DESCRIBE after the execution (OPEN) and before FETCH
The sequence is:
- PREPARE s1 FROM ...
- DECLARE c1 CURSOR FOR s1
- OPEN c1 USING ...
- DESCRIBE s1 INTO dynsqlda
- FETCH c1 INTO dynsqlda
Otherwise it brings no added value.
Seb
------------------------------
Sebastien FLAESCH
Original Message:
Sent: Wed November 19, 2025 05:35 AM
From: Art Kagel
Subject: ESQL/C DESCRIBE OUTPUT after OPEN (with DECLARE CURSOR name) fails with -410
Sebastian:
Yes, I forgot your context. Obviously array fetching is not a valid strategy for your context.
At least the recommendation is out there for others reading the thread who may be able to take advantage.
Art
------------------------------
Art S. Kagel, President and Principal Consultant
ASK Database Management Corp.
www.askdbmgt.com
Original Message:
Sent: Wed November 19, 2025 04:35 AM
From: Sebastien FLAESCH
Subject: ESQL/C DESCRIBE OUTPUT after OPEN (with DECLARE CURSOR name) fails with -410
Thank you Art for your advice!
Understand that we implement the Informix ODI driver for Genero BDL, and the code needs to be generic.
We do not know what SQL statement will be executed by the .4gl code.
We cannot use SET DEFERRED_PREPARE, as we want to leave the option to the end users.
All we know at this driver code context is the actual .4gl instruction (EXECUTE IMMEDIATE / PREPARE / EXECUTE / DECLARE / OPEN / FOREACH / FETCH / CLOSE / FREE / ...) that is to be performed.
In order to implement the .4gl instruction EXECUTE stmt [USING...] [INTO ...], we known if the INTO clause is used.
When an INTO clause is provided, it is because the SQL is producing a result set (SELECT or something else).
So we could switch to a PREPARE / DECLARE / OPEN / DESCRIBE / FETCH, since anyway this is what happens behind the scene when doing PREPARE / EXECUTE INTO ...
Using array fetching is another story, and would require much more code change in our generic code, in order to fetch many rows into a .4gl DYNAMIC ARRAY in one single .4gl FETCH ...
Seb
------------------------------
Sebastien FLAESCH
Original Message:
Sent: Tue November 18, 2025 07:00 AM
From: Art Kagel
Subject: ESQL/C DESCRIBE OUTPUT after OPEN (with DECLARE CURSOR name) fails with -410
Sebastian:
So, if you have IFX_DEFERRED_PREPARE set or have executed SET DEFERRED_PREPARE, you realistically cannot use the PREPARE ... EXECUTE ... INTO paradigm and must use PREPARE...DECLARE CURSOR...OPEN ... FETCH ... CLOSE paradigm in order to be able to DESCRIBE the prepared statement before executing it and fetching the data. All of that is happening under the hood anyway when you just EXECUTE ... INTO, so that is only really saving you a few lines of code no real execution time or saved message trips.
Alternatively, when you want to use PREPARE...EXECUTE in your code, you could use SET DEFERRED_PREPARE to turn the feature off and back on again afterwards.
On your follow-up post, yes, the deferred prepare is working.
If you really want to save execution time in dynamic SQL code, check out array fetching! Your code gets back possibly hundreds of rows in a single FETCH. You just place an array of <whatever> into the sqlda.sqlvar.sqldata field instead of a scalar locations for each returned value and set the FetArrSize global variable to the number of values each array can hold, and poof! That's the biggest performance improver for dynamic SQL code. Look at the code for my dbcopy, dbdelete, or dbmove utility for examples.
Art
------------------------------
Art S. Kagel, President and Principal Consultant
ASK Database Management Corp.
www.askdbmgt.com
Original Message:
Sent: Tue November 18, 2025 03:30 AM
From: Sebastien FLAESCH
Subject: ESQL/C DESCRIBE OUTPUT after OPEN (with DECLARE CURSOR name) fails with -410
Hello,
I have another question related to the DESCRIBE instruction:
With an instruction sequence of type:
- PREPARE s1 FROM ...
- DECLARE c1 CURSOR FOR s1
- OPEN c1 USING ...
- DESCRIBE s1 INTO dynsqlda
- FETCH c1 INTO dynsqlda
I assume that it can be optimized with IFX_DEFERRED_PREPARE, since the DESCRIBE is done after the OPEN and the client should already have column list information returned by the server.
But what about executing a single-row SELECT, with PREPARE + EXECUTE? (remember we need to implement generic code as we don't know what SQL will be executed at runtime)
- PREPARE s1 FROM ...
- EXECUTE s1 USING ... INTO dynsqlda
How can I get column info at runtime with DESCRIBE, and have only one single ping-pong with the server?
The DESCRIBE will create the dynsqlda elements, that will then be used by EXECUTE INTO.
Currently we are doing:
- PREPARE s1 FROM ...
- DESCRIBE s1 INTO dynsqlda
- EXECUTE s1 USING ... INTO dynsqlda
Ideally I would expect to have an extension of EXECUTE:
- PREPARE s1 FROM ...
- EXECUTE s1 USING ... INTO DYNAMIC dynsqlda
where dynsqlca elements are automatically created, and filled with the fetched row.
Or did I miss something?
Seb
------------------------------
Sebastien FLAESCH
Original Message:
Sent: Mon November 17, 2025 11:47 AM
From: Sebastien FLAESCH
Subject: ESQL/C DESCRIBE OUTPUT after OPEN (with DECLARE CURSOR name) fails with -410
Hello,
With ESQL/C 4.50.FC10 (Linux Debian 12):
I am trying to use the DESCRIBE OUTPUT instruction to get column information of a SELECT, after the PREPARE / DECLARE CURSOR / OPEN sequence.
The idea here is to postpone the DESCRIBE OUTPUT after the OPEN, to potentially use the IFX_DEFERRED_PREPARE=1 env var to optimize SQL execution.
I want to use the cursor name used in the DECLARE/OPEN instruction, in the DESCRIBE OUTPUT instruction (since we want to use deferred prepare, I can't use the PREPARE statement name, assuming this would generate a ping/pong with the server - right? Note we have generic code that implies to know only the OPEN cursor name in this context)
With this PREPARE / DECLARE CURSOR cuname / OPEN cuname, the DESCRIBE OUTPUT cuname fails with error
-410 "Prepare statement failed or was not executed."
I am missing something here?
The cursor is declared and opened (=executed), without error, so the SELECT is executed on the server side.
To me it must be possible to use a DESCRIBE OUTPUT only after the OPEN, before starting to FETCH, to benefit from the deferred prepare option.
Warning: We want to use dynamic sqlda, not system descriptors as this would required too much code change.
Here the code:
#include <stdlib.h>#include <stdio.h>#include <signal.h>#include <string.h>void check_sqlcode(const char *msg){ printf(">> [%-40s]: sqlcode=%d sqlerrd[2]=%d\n", msg, sqlca.sqlcode, sqlca.sqlerrd[2]); if (sqlca.sqlcode < 0) { exit(1); }}int main(int argc, char ** argv){ struct sqlda *tmp = NULL; EXEC SQL BEGIN DECLARE SECTION; char *stmt_name = "s1"; char *curs_name = "c1"; char *sqlcmd = "SELECT * FROM systables ORDER BY tabid"; EXEC SQL END DECLARE SECTION; EXEC SQL DATABASE test1; check_sqlcode("DATABASE test1"); EXEC SQL PREPARE :stmt_name FROM :sqlcmd; check_sqlcode("PREPARE");#if 1 EXEC SQL DESCRIBE OUTPUT :stmt_name INTO tmp; check_sqlcode("DESCRIBE OUTPUT using statement name"); fprintf(stdout, ">> Statement type / sqlca.sqlcode: %d\n", sqlca.sqlcode);#endif EXEC SQL DECLARE :curs_name CURSOR FOR :stmt_name; check_sqlcode("DECLARE CURSOR"); EXEC SQL OPEN :curs_name; check_sqlcode("OPEN CURSOR");#if 1 EXEC SQL DESCRIBE OUTPUT :curs_name INTO tmp; check_sqlcode("DESCRIBE OUTPUT using cursor name"); fprintf(stdout, ">> Statement type / sqlca.sqlcode: %d\n", sqlca.sqlcode);#endif}
Seb
------------------------------
Sebastien FLAESCH
------------------------------