Обсуждение: ADO and ODBC: More

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

ADO and ODBC: More

От
"NTB Technical Support"
Дата:
We've done some more investigation into the ODBC/ADO issue involving column
names with embedded spaces.

For the benefit of those that don't know anything about ADO, it makes up its
own SQL statements behind the scenes, so this can't be fixed simply by
changing our SQL query syntax.

For those that do, we're doing something on the lines of

Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "Postgres"
Set RS = Server.CreateObject("ADODB.RecordSet")
SQL = "SELECT ""child beds"" FROM ""dmsbookings"""
RS.Open SQL, Conn, 2, 3
RS("child beds") = 33
RS.Update

The SELECT query runs fine, since that gets passed as is through to the
database. When the recordset is updated, ADO creates its own update query.
As far as we can tell, the following sequence of activity goes on in ODBC:

**** SQLAllocStmt: hdbc = 41250488, stmt = 41295024
CC_add_statement: self=41250488, stmt=41295024
SQLSetStmtOption: entering...
SetStmtOption: SQL_QUERY_TIMEOUT, vParam = 30
SQLGetInfo: entering...fInfoType=29
SQLGetInfo: p='"', len=0, value=0, cbMax=4
SQLGetInfo: entering...fInfoType=41
SQLGetInfo: p='', len=0, value=0, cbMax=4
SQLGetInfo: entering...fInfoType=30
SQLGetInfo: p='<NULL>', len=2, value=32, cbMax=2
SQLGetInfo: entering...fInfoType=34
SQLGetInfo: p='<NULL>', len=2, value=0, cbMax=2
SQLGetInfo: entering...fInfoType=32
SQLGetInfo: p='<NULL>', len=2, value=0, cbMax=2
SQLGetInfo: entering...fInfoType=35
SQLGetInfo: p='<NULL>', len=2, value=32, cbMax=2
SQLColAttributes: entering...
colAttr: col 0 field_type = 23
SQLColAttributes: entering...
colAttr: col 0 field_type = 23
SQLColAttributes: entering...
colAttr: col 0 field_type = 23
SQLColAttr: TABLE_NAME = 'dmsbookings'
SQLColAttributes: entering...
colAttr: col 0 field_type = 23
SQLColAttr: COLUMN_NAME = 'child beds'
SQLColAttributes: entering...
colAttr: col 0 field_type = 23
SQLFreeStmt: entering...hstmt=41295024, fOption=3
SC_free_params:  ENTER, self=41295024
SQLFreeStmt: entering...hstmt=41295024, fOption=0
recycle statement: self= 41295024
SQLPrepare: entering...
**** SQLPrepare: STMT_ALLOCATED, copy
preparing stmt: UPDATE "dmsbookings" SET child beds=? WHERE (child beds=? )
SQLBindParameter: entering...
SQLBindParamater: ipar=0, paramType=1, fCType=-16, fSqlType=4, cbColDef=10,
ibScale=0, rgbValue=1337704, *pcbValue = 4, data_at_exec = 0
SQLBindParameter: entering...
SQLBindParamater: ipar=1, paramType=1, fCType=-16, fSqlType=4, cbColDef=10,
ibScale=0, rgbValue=1337708, *pcbValue = 4, data_at_exec = 0
SQLExecute: entering...
SQLExecute: clear errors...
SQLExecute: copying statement params: trans_status=1, len=59, stmt='UPDATE
"dmsbookings" SET child beds=? WHERE (child beds=? )'
copy_statement_with_params: from(fcType)=-16, to(fSqlType)=4
copy_statement_with_params: from(fcType)=-16, to(fSqlType)=4  stmt_with_params = 'UPDATE "dmsbookings" SET child
beds=33WHERE (child
 
beds=0 )'     it's NOT a select statement: stmt=41295024
send_query(): conn=41250488, query='UPDATE "dmsbookings" SET child beds=33
WHERE (child beds=0 )'
conn=41250488, query='UPDATE "dmsbookings" SET child beds=33 WHERE (child
beds=0 )'
send_query: done sending query
send_query: got id = 'Z'
read 49, global_socket_buffersize=4096
send_query: got id = 'E'
send_query: 'E' - ERROR:  parser: parse error at or near "beds"
ERROR from backend during send_query: 'ERROR:  parser: parse error at or
near "beds"'

I basically don't know anything about ODBC, but it looks to me like
ADO/OLEDB is either getting misled about whether it needs to quote the
column name containing spaces, or it is just not doing it right. I'm
assuming that the previous activity is ADO/OLEDB trying to get the correct
column/table names to build the SQL. I did wonder if changing SQLColAttr to
return a quoted column name would do the trick, but I'm relucant in my
ignorance to do something that might break something else! It's presumably
far too late to try to fix this at the SQLPrepare stage, as the SQL
statement is effectively already unparseable.


Tim




Re: ADO and ODBC: More

От
Tom Lane
Дата:
"NTB Technical Support" <techsupport@ntb.org.uk> writes:
> I basically don't know anything about ODBC, but it looks to me like
> ADO/OLEDB is either getting misled about whether it needs to quote the
> column name containing spaces, or it is just not doing it right.

Curious that it quotes the table name (which doesn't need it) and then
doesn't quote the column name (which does).  Since SQLColAttributes
isn't returning a pre-quoted table name, clearly ADO has heard of the
idea that it ought to quote names.  It's just omitting to do it for
the column name.

I'd write it off as broken code in ADO, and program around it by not
using column names that require quoting.  Ugly answer, but it's not
clear that you have an alternative (short of waiting for an ADO fix).
I don't like the idea of changing what SQLColAttributes returns ...
that seems certain to break other applications.

But first, a wild stab in the dark --- what happens if you writeRS("""child beds""") = 33
ie provide the quotes at the application level?
        regards, tom lane


Re: ADO and ODBC: More

От
"NTB Technical Support"
Дата:
> I'd write it off as broken code in ADO, and program around it by not
> using column names that require quoting.  Ugly answer, but it's not
> clear that you have an alternative (short of waiting for an ADO fix).

I just don't fancy modifying all those hundreds of pages of code... And it
works with SQL Server,
so that would have to be broken in a compatible fashion!

> I don't like the idea of changing what SQLColAttributes returns ...
> that seems certain to break other applications.

That was, my guess too.

> But first, a wild stab in the dark --- what happens if you write
> RS("""child beds""") = 33
> ie provide the quotes at the application level?

Ah. Well. The recordset is a "collection" (like an associative array) whose
contents is created by ADO from the field names of the most-recently
executed query - so """child beds""" would be a non-existent member of the
collection...


Tim



Re: ADO and ODBC: More

От
Tom Lane
Дата:
"NTB Technical Support" <techsupport@ntb.org.uk> writes:
>> I'd write it off as broken code in ADO, and program around it by not
>> using column names that require quoting.  Ugly answer, but it's not
>> clear that you have an alternative (short of waiting for an ADO fix).

> I just don't fancy modifying all those hundreds of pages of
> code... And it works with SQL Server, so that would have to be broken
> in a compatible fashion!

It does eh?  Hmm, that suggests that there is *some* way to make the
right thing happen.  Anyone know how Microsoft's version of
SQLColAttributes acts with such names?
        regards, tom lane


Re: ADO and ODBC: More

От
Hiroshi Inoue
Дата:
Tom Lane wrote:
> 
> "NTB Technical Support" <techsupport@ntb.org.uk> writes:
> >> I'd write it off as broken code in ADO, and program around it by not
> >> using column names that require quoting.  Ugly answer, but it's not
> >> clear that you have an alternative (short of waiting for an ADO fix).
> 
> > I just don't fancy modifying all those hundreds of pages of
> > code... And it works with SQL Server, so that would have to be broken
> > in a compatible fashion!
> 
> It does eh?  Hmm, that suggests that there is *some* way to make the
> right thing happen.  Anyone know how Microsoft's version of
> SQLColAttributes acts with such names?
> 

ADO doesn't need ODBC essentially and M$ SQL Server has
its own OLE DB provider. PostgreSQL doesn't have its OLE
DB provider implementation yet and has to use M$ OLD DB 
provider for ODBC.
I don't know why the table name is quoted but the column
names aren't. There are many applications which quote
column/table names properly(unconditionally?). So it seems
very hard to change SQLxxxx.
Another way is to implement driver cursors. Actually I plan
to implement static/keyset-driven cursors. However I'm not
sure I can do it and couldn't guarantee when it is ready.

regards,
Hiroshi Inoue


Re: ADO and ODBC: More

От
"NTB Technical Support"
Дата:
> > >> I'd write it off as broken code in ADO, and program around it by not
> > >> using column names that require quoting.  Ugly answer, but it's not
> > >> clear that you have an alternative (short of waiting for an ADO fix).

Thanks for the various inputs - looks like this is what we'll have to do.

> ADO doesn't need ODBC essentially and M$ SQL Server has
> its own OLE DB provider. PostgreSQL doesn't have its OLE
> DB provider implementation yet

Just out of curiosity, I ran the ATL OLE DB Provider wizard in VC++ to see
what might be involved in doing this; soon thought better of it....


Tim