Thread: Are multiple selects of the same field allowed using CRecordset::GetFieldValue() ?

Are multiple selects of the same field allowed using CRecordset::GetFieldValue() ?

From
Kristis Makris
Date:
Hello,

I've recently begun using the v7.01.0010 ODBC driver Hiroshi made
available. I'm issuing the following SQL statement:

"SELECT id, id FROM WaterResource"

Using VC++ I'm executing the following:

++++++++++++++
while (!rsNewRecords.IsEOF())
    {
         rsNewRecords.GetFieldValue("id", vID, SQL_C_SLONG);
        rsNewRecords.GetFieldValue(strFieldName, strValue);
        [...]

        rsNewRecords.MoveNext();
    }
++++++++++++++

When execution hits the second .GetFieldValue() call with strFieldname
being = "id" I get an exception, something that did not happen using the
v7.01.0008 driver

As I understand, when .GetFieldName() is used once to retrieve the value
of a field, a subsequent call to retrieve the exact same field fails.
But in the case of selecting (and thus retrieving) a column twice,
shouldn't two calls be possible/allowed for reading that field's value
twice?

Thanks,
-Kristis



Re: Are multiple selects of the same field allowed

From
Hiroshi Inoue
Date:
Kristis Makris wrote:
>
> Hello,
>
> I've recently begun using the v7.01.0010 ODBC driver Hiroshi made
> available. I'm issuing the following SQL statement:
>
> "SELECT id, id FROM WaterResource"
>
> Using VC++ I'm executing the following:
>
> ++++++++++++++
> while (!rsNewRecords.IsEOF())
>         {
>                 rsNewRecords.GetFieldValue("id", vID, SQL_C_SLONG);
>                 rsNewRecords.GetFieldValue(strFieldName, strValue);
>                 [...]
>
>                 rsNewRecords.MoveNext();
>         }
> ++++++++++++++
>
> When execution hits the second .GetFieldValue() call with strFieldname
> being = "id" I get an exception, something that did not happen using the
> v7.01.0008 driver
>
> As I understand, when .GetFieldName() is used once to retrieve the value
> of a field, a subsequent call to retrieve the exact same field fails.
> But in the case of selecting (and thus retrieving) a column twice,
> shouldn't two calls be possible/allowed for reading that field's value
> twice?

Hmm both field have the same field name "id" and the driver
couldn't distinguish them. Couldn't you change the query like
  "select id, id as id2 from WaterResourec"
?

regards,
Hiroshi Inoue

Re: Are multiple selects of the same field allowed

From
Kristis Makris
Date:
>
> Hmm both field have the same field name "id" and the driver
> couldn't distinguish them. Couldn't you change the query like
>   "select id, id as id2 from WaterResourec"
> ?
>

I certainly could, at a great inconvinience of modifying sources of a
huge application that was behaving "normally" so far. I noticed that the
command-line psql client succesfully reports a column's value twice if
instructed to do so:

# select usesysid, usesysid from pg_user;
 usesysid | usesysid
----------+----------
       26 |       26
       27 |       27
       33 |       33
...

How is that implementation different from what I'm trying to achieve
using the .GetField() function? In other languages (e.g. perl using
DBD:Pg) it is possible to get a result of a row, and index in it the
column whose data are to be retrieved. Can't the GetField() be
implemented to function internally in a similar fashion where it marks
which column names it has "visited" already so it moves to the next in
the case of duplicate column names? Or most importantly, why was the
v7.01.0008 driver handling this correctly, while v7.01.0010 isn't? Was a
significant change in an attempt to remain ODBC compliant (or similar)
made that would absolutely, 100% forbid using .GetField() twice on the
same field name? Why is there such a restriction now all of the sudden,
and is that restriction necessary?

Thanks,
-Kristis


Re: Are multiple selects of the same field allowed

From
Hiroshi Inoue
Date:
Kristis Makris wrote:
>
> >
> > Hmm both field have the same field name "id" and the driver
> > couldn't distinguish them. Couldn't you change the query like
> >   "select id, id as id2 from WaterResourec"
> > ?
> >
>
> I certainly could, at a great inconvinience of modifying sources of a
> huge application that was behaving "normally" so far. I noticed that the
> command-line psql client succesfully reports a column's value twice if
> instructed to do so:
>
> # select usesysid, usesysid from pg_user;
>  usesysid | usesysid
> ----------+----------
>        26 |       26
>        27 |       27
>        33 |       33
> ...
>
> How is that implementation different from what I'm trying to achieve
> using the .GetField() function? In other languages (e.g. perl using
> DBD:Pg) it is possible to get a result of a row, and index in it the
> column whose data are to be retrieved.

The problem is you are using
 GetFieldValue(LPCTSTR lpszName, CDBVariant& varValue, short ..
Probably you could get your expected result if you use
 GetFieldValue(short nIndex, CDBVariant& varValue, ..

GetFieldValue() calls SQLGetData() internally. SQLGetData()
uses the index not the name to specifiy the target column.
Using the first style of GetFieldValue(), it searches
the index using the field name first and calls SQLGetData()
using the index. So SQLGetData() has nothing to do with it
and I was wrong at this point in my previous mail.

> Can't the GetField() be
> implemented to function internally in a similar fashion where it marks
> which column names it has "visited" already so it moves to the next in
> the case of duplicate column names? Or most importantly, why was the
> v7.01.0008 driver handling this correctly, while v7.01.0010 isn't? Was a
> significant change in an attempt to remain ODBC compliant (or similar)
> made that would absolutely, 100% forbid using .GetField() twice on the
> same field name?

I changed SQLGetData() to return SQL_NO_DATA if it is
called more than one time in a row for a column containing
fixed-length data because it's a spec of SQLGetData() and
fixes a bug reported by Mika Mantyla. Note that a column
is identified by its index not the name.

I have to think how to deal with your trouble but have
little time now unfortunately.
Please wait for some time.

Anyway I recommend you to use the second style GetFieldValue
or distinguish the same field using alias in future
programming.

regards,
Hiroshi Inoue