Обсуждение: INSERT INTO ... RETURNING id not behaving as expected with SQLNumResultCols

Поиск
Список
Период
Сортировка

INSERT INTO ... RETURNING id not behaving as expected with SQLNumResultCols

От
Ryan Pfeiffer
Дата:
I'm using Postgres 8.4.1 and psqlodbc 08.04.0200. I'm trying to execute a statement INSERT INTO table/values RETURNING
idto get the serial id. Problem is, SQLNumResultCols shows that there are zero columns. The statement I used works fine
inpgadmin. This seems really basic and I am somewhat new to databases and odbc, but does anyone have a solution? 

Thanks,
Ryan




Re: INSERT INTO ... RETURNING id not behaving as expected with SQLNumResultCols

От
Gustavo Pinsard
Дата:
Ryan,

What language are you writing your app? What is the code you're using to
capture the returning id?

Also, are you aware that you can fire a new SELECT statement after
you're done inserting?  In scenarios where you wouldn't have much
concurrency that can be a valid approach.

And don't forget that the OID column is there for you to inspect. Ever
tried a SELECT OID FROM MyTable ORDER BY OID DESC LIMIT 1 ?

Gustavo

On 07/10/2010 01:04, Ryan Pfeiffer wrote:
> I'm using Postgres 8.4.1 and psqlodbc 08.04.0200. I'm trying to execute a statement INSERT INTO table/values
RETURNINGid to get the serial id. Problem is, SQLNumResultCols shows that there are zero columns. The statement I used
worksfine in pgadmin. This seems really basic and I am somewhat new to databases and odbc, but does anyone have a
solution?
>
> Thanks,
> Ryan
>
>
>
>


Вложения

Re: INSERT INTO ... RETURNING id not behaving as expected with SQLNumResultCols

От
Ryan Pfeiffer
Дата:
I'm writing it in visual c++. I've been using DataLayer to interact with ODBC, here:
http://www.codeproject.com/KB/database/DataLayer.aspx

The code in question is:

ret = SQLPrepare(m_hstmt, (SQLCHAR*)selectStatement, SQL_NTS);
if ( ( ret == SQL_SUCCESS ) || ( ret == SQL_SUCCESS_WITH_INFO ) )
{
   SQLSMALLINT numberColumns;

   // Get number of columns in the result set
   ret = SQLNumResultCols(m_hstmt, &numberColumns);

&numberColumns comes up as 0. Can SQLPrepare not be used the way I want for INSERT INTO ... RETURNING?

And yes, I'm aware I could use another select statement, and concurrency would *probably* not be an issue down the
road,but it bothers me that it is possible I could get the wrong ID. I suppose I can just SELECT id WHERE val1 = x,
val2= y, and so on as there should not be any exact duplicates in my tables that I can think of at this point. Still
earlyon in development though. 

Thanks,
Ryan

--- On Thu, 10/7/10, Gustavo Pinsard <pinsard@rocksolid.com.br> wrote:

> From: Gustavo Pinsard <pinsard@rocksolid.com.br>
> Subject: Re: [ODBC] INSERT INTO ... RETURNING id not behaving as expected with SQLNumResultCols
> To: pgsql-odbc@postgresql.org
> Date: Thursday, October 7, 2010, 6:11 AM
> Ryan,
>
> What language are you writing your app? What is the code
> you're using to
> capture the returning id?
>
> Also, are you aware that you can fire a new SELECT
> statement after
> you're done inserting?  In scenarios where you
> wouldn't have much
> concurrency that can be a valid approach.
>
> And don't forget that the OID column is there for you to
> inspect. Ever
> tried a SELECT OID FROM MyTable ORDER BY OID DESC LIMIT 1
> ?
>
> Gustavo
>
> On 07/10/2010 01:04, Ryan Pfeiffer wrote:
> > I'm using Postgres 8.4.1 and psqlodbc 08.04.0200. I'm
> trying to execute a statement INSERT INTO table/values
> RETURNING id to get the serial id. Problem is,
> SQLNumResultCols shows that there are zero columns. The
> statement I used works fine in pgadmin. This seems really
> basic and I am somewhat new to databases and odbc, but does
> anyone have a solution?
> >
> > Thanks,
> > Ryan
> >
> >
> >
> >
>
>




Re: INSERT INTO ... RETURNING id not behaving as expected with SQLNumResultCols

От
Gustavo Pinsard
Дата:
Ryan,

You seem to have a buffer problem.  As you know you have to declare
which columns you want returned from the INSERT statement. Thus, you
need a compatible buffer to receive each column declared.

As you didn't inform how you're mounting your statement, nor the struct
to hold the results of it, I can't say for sure.

But here is an example of how I deal with INSERT RETURNING, in my
language of choice: Clarion.

   PROGRAM

   MAP
   END

szDBConn      CSTRING( 512 )
tblDummy      FILE, DRIVER( 'ODBC' ), NAME( 'dummy' ), OWNER( szDBConn )
RECORD          RECORD
id                ULONG
                 END
               END


   ! Clarion has roots in Cobol, and the following statement
   ! declares the executable part of the program
   CODE

   ! Lets prepare the connection string
   szDBConn = 'Driver={{PostgreSQL ANSI};database=test;uid=test;pwd=test'

   ! Lets open the "file", which is in reality just a buffer pointing
   ! to a table in a server, according to the "OWNER" modifier
   OPEN( tblDummy, 42h )

   ! Here I send the command I want - " & | " instructs to continue
   ! on the next line.  Clarion doesn't use ";" as an end of statement
   ! marker, but the \n\r sequence, and when we need, well, you figured.
   tblDummy{ PROP:SQL } = 'INSERT INTO customers ' & |
                          'VALUES ( 'GUSTAVO' ) ' & |
                          'RETURNING id'

   ! HERE IT IS - read whatever the server returned
   NEXT( tblDummy )

   ! This is a MessageBox() alright.
   MESSAGE( tblDummy.id )

   ! Ends program
   RETURN 0

The above code holds a complete program that will connect to a server
(given teh connection strings is valid, off course), and issue an INSERT
command against an existing "customers" table.

Now, how do I SEND the SQL command to de server? Using the transport
buffer I declared: tblDummy.  This buffer reflects an existing table (or
view) in the database.  In this case, a table called "dummy".

In Clarion, when I issue a PROP:SQL command attached to a buffer, the
server responds back the informed buffer.  Then, a simple NEXT() will
read the contents of the buffer, which is a struct at the end of the
day, and I'm all set.

This tip of having a dummy table or view declared may help you to
collect different types of information from the server, not always
related to data tables.  You can, for that matter, ask the server who is
logged, for how long, its version etc.

It is just a matter of having a compatible buffer to receive whatever
the server sends back in response to a command.

HTH

Gustavo


Вложения

Re: INSERT INTO ... RETURNING id not behaving as expected with SQLNumResultCols

От
Ryan Pfeiffer
Дата:
Ok, I believe I have found the problem.

http://msdn.microsoft.com/en-us/library/ms711684(v=VS.85).aspx

"The application can call SQLNumResultCols at any time after the statement is prepared or executed. However, because
somedata sources cannot easily describe the result sets that will be created by prepared statements, performance will
sufferif SQLNumResultCols is called after a statement is prepared but before it is executed." 

I suppose that's what I get for slapping an existing library into my software without completely understanding it. If I
understandwhat I've read correctly, SQLPrepare should only be used if I plan on repeating the same statement over and
overwith different variables. 

Since this is a simple wrapper, it seems that an error may have been made. It calls SQLPrepare each time the wrapper
classesare used, so even if it was repeated many times, SQLPrepare is still being called each time which I think is not
useful.Not sure on that though. At this point I moved up SQLExecute and I got the results I expected. 

--- On Thu, 10/7/10, Ryan Pfeiffer <malice_ryan@yahoo.com> wrote:

> From: Ryan Pfeiffer <malice_ryan@yahoo.com>
> Subject: Re: [ODBC] INSERT INTO ... RETURNING id not behaving as expected with SQLNumResultCols
> To: pgsql-odbc@postgresql.org
> Date: Thursday, October 7, 2010, 12:51 PM
> I'm writing it in visual c++. I've
> been using DataLayer to interact with ODBC, here: http://www.codeproject.com/KB/database/DataLayer.aspx
>
> The code in question is:
>
> ret = SQLPrepare(m_hstmt, (SQLCHAR*)selectStatement,
> SQL_NTS);
> if ( ( ret == SQL_SUCCESS ) || ( ret ==
> SQL_SUCCESS_WITH_INFO ) )
> {
>    SQLSMALLINT numberColumns;
>
>    // Get number of columns in the result
> set
>    ret = SQLNumResultCols(m_hstmt,
> &numberColumns);
>
> &numberColumns comes up as 0. Can SQLPrepare not be
> used the way I want for INSERT INTO ... RETURNING?
>
> And yes, I'm aware I could use another select statement,
> and concurrency would *probably* not be an issue down the
> road, but it bothers me that it is possible I could get the
> wrong ID. I suppose I can just SELECT id WHERE val1 = x,
> val2 = y, and so on as there should not be any exact
> duplicates in my tables that I can think of at this point.
> Still early on in development though.
>
> Thanks,
> Ryan
>
> --- On Thu, 10/7/10, Gustavo Pinsard <pinsard@rocksolid.com.br>
> wrote:
>
> > From: Gustavo Pinsard <pinsard@rocksolid.com.br>
> > Subject: Re: [ODBC] INSERT INTO ... RETURNING id not
> behaving as expected with SQLNumResultCols
> > To: pgsql-odbc@postgresql.org
> > Date: Thursday, October 7, 2010, 6:11 AM
> > Ryan,
> >
> > What language are you writing your app? What is the
> code
> > you're using to
> > capture the returning id?
> >
> > Also, are you aware that you can fire a new SELECT
> > statement after
> > you're done inserting?  In scenarios where you
> > wouldn't have much
> > concurrency that can be a valid approach.
> >
> > And don't forget that the OID column is there for you
> to
> > inspect. Ever
> > tried a SELECT OID FROM MyTable ORDER BY OID DESC
> LIMIT 1
> > ?
> >
> > Gustavo
> >
> > On 07/10/2010 01:04, Ryan Pfeiffer wrote:
> > > I'm using Postgres 8.4.1 and psqlodbc 08.04.0200.
> I'm
> > trying to execute a statement INSERT INTO
> table/values
> > RETURNING id to get the serial id. Problem is,
> > SQLNumResultCols shows that there are zero columns.
> The
> > statement I used works fine in pgadmin. This seems
> really
> > basic and I am somewhat new to databases and odbc, but
> does
> > anyone have a solution?
> > >
> > > Thanks,
> > > Ryan
> > >
> > >
> > >
> > >
> >
> >
>
>
>
>
> --
> Sent via pgsql-odbc mailing list (pgsql-odbc@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-odbc
>