Irishboy24 has asked for the wisdom of the Perl Monks concerning the following question:

hey monks, i wrote a simple perl script that connects to the db and fetches a row and prints it out. when i try to run the code it comes back saying that it cannot find DBI.pm in @INC. this same code was working a few weeks ago, so i am not sure what went wrong as i have not changed anything. i use CYGWIN.please help

#!/usr/bin/perl push (@INC, "D:\\Perl\\site\\lib"); use DBI; my $dbh = DBI->connect("dbi:SQL Server;database=Maddy17","Maddy",""); my $sth = $dbh->prepare ("select * from sysobjects where name = 'pub_titles' and type = 'P' and uid = USER_ID()"); my $sth->execute(); while (@row = $sth->fetchrow_aray()) { if (-e @row) { print "store proc exists\n"; } } my $dbh->disconnect();

Replies are listed 'Best First'.
Re: Cant locate DBI in @INC
by almut (Canon) on Sep 17, 2009 at 15:48 UTC

    You'd need to put the push (@INC, "D:\\Perl\\site\\lib"); in a BEGIN block for it to be of any help for the subsequent use DBI;.  Otherwise, the use DBI (which itself implies a BEGIN block) would be run before you have manipulated @INC.

    BEGIN { push (@INC, "D:\\Perl\\site\\lib"); } use DBI;

    Or simply

    use lib "D:\\Perl\\site\\lib"; use DBI;

    (The latter would also put the additional lib path in front of the array (like unshift @INC would) — which usually is what you want.)

      i tried your way and it throws the following error

      $ perl data.pl 8 [main] perl 4524 _cygtls::handle_exceptions: Error while dumpi +ng state ( probably corrupted stack) Segmentation fault (core dumped)

        This shows that the @INC manipulation actually had an effect this time :)

        Unfortunately, the module that was found under D:\\Perl\\site\\lib apparently isn't binary compatible with your perl (most likely, the shared lib associated with the DBD part is the culprit).

        Anyhow, you said it did work before. So - as the @INC manipulation cannot have had any effect before - some other module must have been found at the time (under the default lib paths)... Maybe you can reconstruct which version/build of DBI/DBD and perl that had been.  Otherwise you'll likely have to reinstall the DB modules.

Re: Cant locate DBI in @INC
by ELISHEVA (Prior) on Sep 17, 2009 at 16:18 UTC

    If nothing changed in your script, then something changed in your environment. As almut has already pointed out, even a few weeks ago the push (@INC, "D:\\Perl\\site\\lib"); line had no effect since it was being executed after the use DBI statement. Previously, "D:\\Perl\\site\\lib" was already in @INC when your script began. Now it is no longer present.

    In addition to the fix that almut has suggested (moving push (@INC, "D:\\Perl\\site\\lib"); into a BEGIN {...} block placed before use DBI you might want to look more closely at your environment to see what changed. Look particularly for changes in PATH, PERL5LIB, PERLLIB environment variables. Also if perl is running inside of a .bat file with command line switches, look for changes in the values passed to the -I argument. It is possible that other scripts you have written will have been affected by whatever changed. See perlrun for more information about what contributes to the value of @INC when your script runs.

    Best, beth

      Thank you monks for all the replies. i guess the only plausible solution now for me is to reinstall the DBI module from CPAN. i will be on it.

Re: Cant locate DBI in @INC (BEGIN)
by ikegami (Patriarch) on Sep 17, 2009 at 16:32 UTC

    This post adds to almut's post in case you want more details on compilation and execution order. If you don't, then skip this post.

    use Module;
    is the same as
    BEGIN { require Module; Module->import(); }

    (In fact, in existing versions of Perl, the parser can't tell the difference and that's the source of a bug unrelated to this post.)

    BEGIN blocks are execute as soon as they are compiled, so

    push (@INC, "D:\\Perl\\site\\lib"); use DBI;
    is executed as follows:
    1. push (@INC, "D:\\Perl\\site\\lib"); is compiled.
    2. require DBI; is compiled.
    3. DBI->import(); is compiled.
    4. require DBI; is executed (by virtue of being in a BEGIN block).
    5. DBI->import(); is executed (by virtue of being in a BEGIN block).
    6. The rest of the program is compiled.
    7. The compilation phase ends and the execution phase begins.
    8. push (@INC, "D:\\Perl\\site\\lib"); is executed.
    9. The rest of the program is executed.

    As you can see, the modification of @INC happens much much too late.