On 12-Feb-2002 Jeff Urlwin wrote:
> <snip>
>
>>
>> >> > > DBI->connect(database=onetoone;host=64.78.148.124;port=1071)
>> >> > > failed: [iODBC][Driver Manager]Invalid string or buffer
>> >> length (SQL-S1090)
>>
>> This happens because DBD::ODBC tries to use SQLDriverConnect
>> first and if that
>> fails it uses SQLConnect. SQLConnect in the ODBC spec is defined
>> as taking a
>> Server string (the first arg to SQLConnect) no longer than
>> SQL_MAX_DSN_LENGTH
>> which is usually 32.
>
> Hmmm...I wonder if I should skip the SQLConnect, if the string is longer
> than SQL_MAX_DSN_LENGTH?
>
>
>>
>> >> > > [iODBC][Driver Manager]Data source name not found and no default
>> >> > > driver specified. Driver could not be loaded (SQL-IM002)(DBD:
>> >> > > db_login/SQLConnect err=-1) at t/02simple.t line 13
>>
>> You did not appear to specify a driver in the connect string. You need to
>> specify one of DSN=, DRIVER= or FILEDSN=.
Ages ago when I discovered DBD::ODBC was calling SQLConnect and if that failed,
SQLDriverConnect I relaxed the SQL_MAX_DSN_LENGTH checking in OOB. OOB maps
the Server, Username and Password parameters to SQLConnect to
SQLDriverConnect("DSN=ServerName,UID=Username;PWD=password") so if someone
calls DBI->connect with a connection string containing attributes separated
by semicolons it continued to work so long as the DSN name was first in
the string. This was way before there was a reasonable ODBC driver manager for
UNIX and just after DBD::ODBC introduced the requirement for SQLDrivers and
SQLDataSources support (apparently relaxed in later versions).
Now that most people use an ODBC driver manager under DBD::ODBC this has
returned to not working as I planned as the driver manager tends to throw out
the call to SQLConnect due to SQL_MAX_DSN_LENGTH before I see it and then
DBD::ODBC falls back on SQLDriverConnect and it works.
As a result, your suggestion of only using SQLDriverConnect (skipping
SQLConnect) if the connection string is > SQL_MAX_DSN_LENGTH would probably work
except for the recent code which allows DBD::ODBC to link directly with a
driver that does not support SQLDriverConnect (what would happen in this case).
The OOB FAQ specifically suggests users of DBD::ODBC, unixODBC and OOB use
DBI->connect('dbi:ODBC:DSN=xxx',...) because it allows longer connection
strings and automatically fails SQLConnect code but until recent patches I
supplied to you this had the down side of leaving an ODBC diagnostic on the
stack for SQLConnect failures which was seen if something went wrong later.
I guess if first arg to DBI->connect is longer than SQL_MAX_DSN_LENGTH then
calling SQLDriverConnect or signalling an error (if linked directly to driver
which does not have SQLDriverConnect) would be perfectly reasonable as the
driver manager or driver being called with this long string is only likely to
throw it out as too long anyway when called for SQLConnect.
However, my personal preference would be to call SQLDriverConnect FIRST unless
the driver has #ifdef code in DBD::ODBC saying it does not have
SQLDriverConnect. Reasoning - unless the connection string is wrong, it
connects every time, first time, instead of possible failing in SQLConnect, only
to result in calling SQLDriverConnect anyway. As far as my reading
(and experience) of the ODBC spec is concerned I do not see any reason
why a reversal of the ordering would have any adverse affects - there
is no ODBC versioning issue inferred by using SQLDriverConnect
instead of SQLConnect. Obviously, I have a bias here but I do not think it would
break anything in other drivers if changed this way - partly based on the fact
that OOB never transfers an SQLConnect call as SQLConnect but instead uses
SQLDriverConnect (as in paragraph above).
Martin
--
Martin J. Evans
Easysoft Ltd, UK
Development