I didn't write the data_sources method but I look after DBD::ODBC these days. I don't see a 64bit issue and inspecting the code I cannot see any issue although there are things I might have done differently.
I still suspect it is something to do with the large number of DSNs you have. If you download DBD::ODBC and build it yourself I can suggest a few small changes that might help identify the issue.
Download the latest DBD::ODBC, and untar it into a dir. Open a strawberry perl shell session and change to the dir above. Edit the file ODBC.xs and delete the function data_sources and replace it with the one below:
void
data_sources(drh, attr = NULL)
SV* drh;
SV* attr;
PROTOTYPE: $;$
PPCODE:
{
#ifdef DBD_ODBC_NO_DATASOURCES
/* D_imp_drh(drh);
imp_drh->henv = SQL_NULL_HENV;
dbd_error(drh, (RETCODE) SQL_ERROR, "data_sources: SOLID d
+oesn't implement SQLDataSources()");*/
XSRETURN(0);
#else
int numDataSources = 0;
SQLUSMALLINT fDirection = SQL_FETCH_FIRST;
RETCODE rc;
SQLCHAR dsn[SQL_MAX_DSN_LENGTH+1+9 /* strlen("DBI:ODBC:") */];
SQLSMALLINT dsn_length;
SQLCHAR description[256];
SQLSMALLINT description_length;
D_imp_drh(drh);
if (!imp_drh->connects) {
rc = SQLAllocEnv(&imp_drh->henv);
if (!SQL_ok(rc)) {
imp_drh->henv = SQL_NULL_HENV;
dbd_error(drh, rc, "data_sources/SQLAllocEnv");
XSRETURN(0);
}
}
strcpy(dsn, "dbi:ODBC:");
while (1) {
description[0] = '\0';
rc = SQLDataSources(imp_drh->henv, fDirection,
dsn+9, /* strlen("dbi:ODBC:") */
SQL_MAX_DSN_LENGTH,
&dsn_length,
description, sizeof(description),
&description_length);
if (!SQL_ok(rc)) {
if (rc != SQL_NO_DATA_FOUND) {
/*
* Temporarily increment imp_drh->connects, so
* that dbd_error uses our henv.
*/
imp_drh->connects++;
dbd_error(drh, rc, "data_sources/SQLDataSources");
imp_drh->connects--;
}
break;
}
printf("/%s/ (%d), /%s/ (%d)\n",
(dsn + 9), dsn_length,
description, description_length);
ST(numDataSources++) = newSVpv(dsn, dsn_length+9 /* strlen("db
+i:ODBC:") */ );
fDirection = SQL_FETCH_NEXT;
}
if (!imp_drh->connects) {
SQLFreeEnv(imp_drh->henv);
imp_drh->henv = SQL_NULL_HENV;
}
XSRETURN(numDataSources); /* return indicating #
+ items on stack */
#endif /* no data sources */
}
Now type perl Makefile.PL, then dmake and it should build you a DBD::ODBC. Now run something like the following:
perl -Ic:\path_to_dbd_odbc_dir\blib\lib -Ic:\path_to_dbd_odbc_dir\blib
+\arch -le "use DBI; my @a = DBI->data_sources('ODBC');"
Replace c:\path_to_dbd_odbc_dir as per your machine and where you unpacked DBD::ODBC. It should output a list of your dsns and lengths - what was the output and did it crash? If it does not crash, take the printf line out (all from printf to the semi colon), rebuild and try again? Does it work now? |