1
votes

I have a problem where-by I cannot get Perl DBD::ODBC to use unixODBC after re-compiling and re-installing. It had been previously installed.

I had compiled DBD::ODBC to use the DataDirect ODBC Driver Manager. I now want to recompile it to use unixODBC. However, despite starting with fresh source, configuring (it picks up unixODBC), and then compiling and installing, it seems to be stuck using the DataDirect ODBC Driver Manager. I've gone as far as deleting all the files (I know of) from the Perl module folders, but the problem remains when it's reinstalled.

I'm compiling from source because the server I'm installing on doesn't have an Internet connection, so I haven't been using CPAN.

I'm using unixODBC 1.2.3 with Perl 5.8.4 (it matches the environment) on Solaris 10.

I've removed all I can find:

 1. cd /usr/perl5/site_perl/5.8.4/sun4-solaris-64int/auto/DBD/
 2. sudo rm -R ODBC
 3. cd /usr/perl5/site_perl/5.8.4/sun4-solaris-64int/DBD/
 4. sudo rm -R ODBC
 5. sudo rm ODBC.pm
 6. cd /usr/perl5/5.8.4/man/man3/
 7. sudo rm DBD::ODBC.3
 8. sudo vi /usr/perl5/5.8.4/lib/sun4-solaris-64int/perllocal.pod

I then removed all entries for DBD::ODBC in perllocal.pod.

I can see when I run perl Makefile.PL that it is finding unixODBC.

Looking for odbc_config at /usr/local/unixODBC_sp64/bin/odbc_config
  Found odbc_config (via /usr/local/unixODBC_sp64/bin/odbc_config) version 2.3.2

  odbc_config reports --prefix=/usr/local/unixODBC_sp64
  odbc_config reports --include-prefix=/usr/local/unixODBC_sp64/include
  odbc_config reports --lib-prefix=/usr/local/unixODBC_sp64/lib
  ODBC INC dir set to /usr/local/unixODBC_sp64/include from odbc_config
  ODBC LIB dir set to /usr/local/unixODBC_sp64/lib from odbc_config
Using ODBC HOME /usr/local/unixODBC_sp64

This looks like a unixodbc type of driver manager.
Looking for odbcinst
  odbcinst -j reports:

unixODBC 2.3.2
DRIVERS............: /usr/local/unixODBC_sp64/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/unixODBC_sp64/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/unixODBC_sp64/etc/ODBCDataSources
USER DATA SOURCES..: /usr/local/unixODBC_sp64/etc/odbc.ini

Here are all environment variables relating to ODBC in the environment on which I'm compiling and installing the module

LD_LIBRARY_PATH=/usr/local/unixODBC_sp64/lib:
LD_LIBRARY_PATH_64=/usr/local/unixODBC_sp64/lib:
PATH=/usr/local/unixODBC_sp64/bin:/usr/sfw/bin:/usr/ccs/bin:/opt/SUNWspro/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/bin
ODBCINI=/usr/local/unixODBC_sp64/etc/odbc.ini
ODBCHOME=/usr/local/unixODBC_sp64

When I run a test I still see an error from the DataDirect driver manager:

DBI connect('lksdjhf','ljkshdf',...) failed: [DataDirect][ODBC lib] System information file not found. Please check the ODBCINI environment variable. (SQL-IM002) at ./test_odbcdb2.pl line 19

Ignore the fact that it can't find the driver, because odbc.ini isn't populated. I'm testing with a junk connection because I want to see this same error message from unixODBC.

The Perl script I'm using for testing is below. It works with the DataDirect driver manager.

#!/usr/bin/perl -w

use DBI;
use DBD::ODBC;
use DBD::DB2::Constants;

print "Enter Data Source Name:";
my $dsn =<STDIN>;
chomp $dsn;
my $data_source = "DBI:ODBC:$dsn";
print "Enter Username:";
my $user =<STDIN>;
print "Enter password:";
my $password =<STDIN>;
chomp $user;
chomp $password;

# Connect to the db2 database using odbc
my $dbh = DBI->connect($data_source, $user, $password, {AutoCommit =>1})
                or die "Can't connect to $data_source: $DBI::errstr";
$stmt = "SELECT current timestamp from sysibm.sysdummy1; ";
$sth = $dbh->prepare($stmt);
$sth->execute();

#associate variable with output columns...

$sth->bind_col(1,\$timestap);
while ($sth->fetch) {
           print "The time is: $timestap\n";
}
$dbh->disconnect;
1
what does ./test_odbcdb2.pl line 19 contain?slayedbylucifer
my $dbh = DBI->connect($data_source, $user, $password, {AutoCommit =>1}) or die "Can't connect to $data_source: $DBI::errstr";LokMac
@slayedbylucifer - I've added the full test Perl script to the question. Thanks.LokMac
In the past, I have used unixodbc along with freetds. and I would do connectivity test using tql and isql before moving on to perl. Check one of my answers from another post if it helps you: stackoverflow.com/a/21252539/1251660slayedbylucifer
Thanks @slayedbylucifer, but there is no connectivity issue using isql that comes with unixODBC. I'm not even getting to the point of connectivity as a result of DBD::ODBC not referencing the correct driver manager.LokMac

1 Answers

3
votes

You didn't say if you did a make install at the end of the build but I'll assume you did.

You didn't say if those LD_LIBRARY_xx env vars are just set or exported as well.

Firstly, addressing other comments.

  1. "DBI:ODBC:$dsn" should indeed be "dbi:ODBC:$dsn".
  2. Perl DBI does load the driver based on the string after "dbi:" so "ODBC" loads the DBD::ODBC module.
  3. "It is at the time of DBD::ODBC configuration that it selects which ODBC driver manager to use" is not correct. Configuration only selects the driver manager to compile against. I don't believe a "runpath" instruction to the linker is provided at link time. So you could happily build against unixODBC and run against DD which you seem to be doing.

Find ODBC.so in your Perl tree (it should be in a dir called DBD/ODBC something like /home/martin/perl5/perlbrew/perls/perl-5.19.10/lib/site_perl/5.19.10/x86_64-linux/auto/DBD/ODBC/ODBC.so). Now run "ldd ODBC.so" on it and look to see in the output where the libodbc.so comes from e.g.:

$ ldd ./blib/arch/auto/DBD/ODBC/ODBC.so
        libodbc.so.1 =>  /usr/local/lib/libodbc.so.1
        libdl.so.1 =>    /usr/lib/libdl.so.1
        libthread.so.1 =>        /usr/lib/libthread.so.1
        libc.so.1 =>     /usr/lib/libc.so.1
        /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1

Here the dynamic linker is resolving the dependency on libodbc.so.1 with /usr/local/lib/libodbc.so.1. You need to tell the dynamic linker to look in your unixODBC lib dir before wherever it is looking now. Using LD_LIBRARY_PATH might not work - especially if you run as root and there are global ways of telling the dynamic liker where to look. Read your ld.so.1 section 1 man page.