logo       

Re: [ECPG] Multiple cursors in the same transaction: msg#00015

Subject: Re: [ECPG] Multiple cursors in the same transaction
WITH HOLD worked just fine.

Thanks a lot.


-----Original Message-----
From: pgsql-interfaces-owner@xxxxxxxxxxxxxx
[mailto:pgsql-interfaces-owner@xxxxxxxxxxxxxx]On Behalf Of Bruce Momjian
Sent: Monday, June 07, 2004 4:50 PM
To: Stergios Zissakis
Cc: Interfaces; Kostas Lykiardopoulos; Dimitris Pantermalis
Subject: Re: [INTERFACES] [ECPG] Multiple cursors in the same transaction



Cursors are automatically closed at the end of a transaction.  You can
use WITH HOLD on the cursor to bypass that if you are running 7.4.X.

---------------------------------------------------------------------------

Stergios Zissakis wrote:
> Dear ECPG support,
>
> During a port from Oracle I came accross a problem where a cursor is lost
> when a commit is performed. Consider the following piece of code:
>
> EXEC SQL WHENEVER SQLERROR DO call_sql_error_function(...);
>
> EXEC SQL CONNECT TO :connect_str USER :username IDENTIFIED BY :password;
>
> sprintf((char *) del_stmt.arr, "select columns from delete_table;\0");
> EXEC SQL PREPARE Delete FROM del_stmt;
> EXEC SQL DECLARE del1 CURSOR FOR Delete;
> EXEC SQL OPEN del1;
>
> EXEC SQL WHENEVER NOT FOUND DO break;
>
> while( true )
> {
>   EXEC SQL FETCH FROM del1 INTO :dlt;
>   ...
>   sprintf((char *) stmt.arr, "select to_char((date_trunc('month',
> localtimestamp) - interval '%d month'), 'MM/DD/YYYY HH24:MI:SS');\0",
> months);
>   EXEC SQL PREPARE S1 FROM :stmt;
>   EXEC SQL DECLARE mytime CURSOR FOR S1;
>   EXEC SQL OPEN mytime;
>   EXEC SQL FETCH mytime INTO :mydate;
>   EXEC SQL CLOSE mytime;
>   ...
>   sprintf((char *) select_stmt, "select ... from ... where ...;\0", ...);
>   EXEC SQL PREPARE ARCH FROM :select_stmt;
>   EXEC SQL DECLARE SEL_CURS CURSOR FROM ARCH;
>   EXEC SQL OPEN SEL_CURS;
>   EXEC SQL WHENEVER NOT FOUND DO break;
>
>   while( true )
>   {
>     EXEC SQL FETCH :rows_to_fetch FROM SEL_CURS INTO :alarm_records;
>     for( int i = 0; i < sqlca.sqlerrd[2]; i++ )
>     {
>     ...
>     }
>   }
>   EXEC SQL CLOSE SEL_CURS;
>   ...
>   EXEC SQL WHENVER NOT FOUND goto somewhere;
>   sprintf((char *) del2_stmt, "delete from %s where %s;\0", from, where);
>   EXEC SQL PREPARE DEL2 FROM :del2_stmt;
>   EXEC SQL EXECUTE DEL2;
>   EXEC SQL COMMIT; // I think this commit causes the problem... see the
> comments further down.
>
> somewhere:
>   ...
> }
>
> EXEC SQL CLOSE del1;
> EXEC SQL COMMIT WORK RELEASE;
>
> The problem is that fetching the second time round from the del1 cursor
> cause the app to bomb out. The postmaster log  displays the following
> message: "... ERROR: cursor del1 does not exist". Any ideas why this is
> happening? Who come del1 dissapears whithout closing it? Notice that my
> delete_table (del_stmt statement at the beginning) contains a single row;
so
> the second time a fetch is performed it should simply not found anything
and
> do a break to terminate the loop.
>
> The work-around I found was to split the work in two different connections
> (contexts); one for selecting from the delete_table and the other for the
> rest of the statements. This way everything works fine but I cannot really
> afford an extra connection for this (my app has already 20 connections by
> design). Here is the code that solved the problem:
>
> EXEC SQL WHENEVER SQLERROR DO call_sql_error_function(...);
>
> EXEC SQL CONNECT TO :connect_str AS :ctx1 USER :username IDENTIFIED BY
> :password;
> EXEC SQL CONNECT TO :connect_str AS :ctx2USER :username IDENTIFIED BY
> :password;
>
> sprintf((char *) del_stmt.arr, "select columns from delete_table;\0");
> EXEC SQL PREPARE Delete FROM del_stmt;
> EXEC SQL AT :ctx1 DECLARE del1 CURSOR FOR Delete;
> EXEC SQL AT :ctx1 OPEN del1;
>
> EXEC SQL WHENEVER NOT FOUND DO break;
>
> while( true )
> {
>   EXEC SQL AT :ctx1 FETCH FROM del1 INTO :dlt;
>   ...
>   sprintf((char *) stmt.arr, "select to_char((date_trunc('month',
> localtimestamp) - interval '%d month'), 'MM/DD/YYYY HH24:MI:SS');\0",
> months);
>   EXEC SQL PREPARE S1 FROM :stmt;
>   EXEC SQL AT :ctx2 DECLARE mytime CURSOR FOR S1;
>   EXEC SQL AT :ctx2 OPEN mytime;
>   EXEC SQL AT :ctx2 FETCH mytime INTO :mydate;
>   EXEC SQL AT :ctx2 CLOSE mytime;
>   ...
>   sprintf((char *) select_stmt, "select ... from ... where ...;\0", ...);
>   EXEC SQL PREPARE ARCH FROM :select_stmt;
>   EXEC SQL AT :ctx2 DECLARE SEL_CURS CURSOR FROM ARCH;
>   EXEC SQL AT :ctx2 OPEN SEL_CURS;
>   EXEC SQL WHENEVER NOT FOUND DO break;
>
>   while( true )
>   {
>     EXEC SQL AT :ctx2 FETCH :rows_to_fetch FROM SEL_CURS INTO
> :alarm_records;
>     for( int i = 0; i < sqlca.sqlerrd[2]; i++ )
>     {
>     ...
>     }
>   }
>   EXEC SQL AT :ctx2 CLOSE SEL_CURS;
>   ...
>   EXEC SQL WHENVER NOT FOUND goto somewhere;
>   sprintf((char *) del2_stmt, "delete from %s where %s;\0", from, where);
>   EXEC SQL PREPARE DEL2 FROM :del2_stmt;
>   EXEC SQL AT :ctx2 EXECUTE DEL2;
>   EXEC SQL AT :ctx2 COMMIT;
>
> somewhere:
>   ...
> }
>
> EXEC SQL AT :ctx1 CLOSE del1;
> EXEC SQL COMMIT WORK RELEASE;
>
>
>
> Is there any other solution to this problem?
>
> Thanks in advance.
>
> Stergios Zissakis
>
> Intracom S.A.
> Network Management Systems Dept.
> Paiania
> Athens
> Greece
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 9: the planner will ignore your desire to choose an index scan if your
>       joining column's datatypes do not match
>

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@xxxxxxxxxxxxxxxx               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
    (send "unregister YourEmailAddressHere" to majordomo@xxxxxxxxxxxxxx)


---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings



<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

Recently Viewed:
audio.irate.dev...    yellowdog.gener...    ietf.ips/2002-0...    xfree86.fonts/2...    busybox/2003-07...    emacs.jdee/2004...    linux.mandrake....    hardware.microc...    user-groups.lin...    science.analysi...    version-control...    db.filemaker.de...    cluster.openmos...    mail.eyebrowse....    text.xml.xerces...    kde.devel.kwrit...    finance.moneyda...    gcc.regression/...    network.routing...    os.freebsd.deve...    recreation.radi...    qnx.openqnx.dev...    python.xml/2002...   
Home | blog view | USPTO Patent Archive | advertise | OSDir is an inevitable website. super tiny logo

Free Magazines

Cisco News
Receive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business.
subscribe

Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field.
subscribe

The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business.
subscribe

Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company.
subscribe

Total Telecom Total Telecom is "The Economist of the communications industry".
subscribe