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

Dear Monks, I am runnng an sql query using DBI. The code works well on my laptop running Strawberry Perl but fails to run on our university linux server using Perl 5.10.1

My perl progam is

#!/usr/bin/perl use strict; use warnings; use Text::CSV; use DBI; sub RunSqlSearch; my $query = qq(SELECT sid,genotype FROM newCsv.csv WHERE genotype = 'a +'); my ($queryResult,@sidResult) = RunSqlSearch($query); print "You query $query returned the following result:$queryResult\n"; print "The sid list associated with this result are: @sidResult\n\n"; sub RunSqlSearch($){ my $query = $_[0]; # error check # if ($query eq ""){die "No value entered for $query $!\n";} # Connect to the database, (the directory containing our csv file +(s)) my $dbh = DBI->connect ("dbi:CSV:", undef, undef, { f_dir => ".", f_ext => ".csv/r", f_encoding => "utf-8", RaiseError => 1, }) or die $DBI::errstr; # Output using sql query # my $sth = $dbh->prepare($query); $sth->execute; my @row; my $queryResult=""; my @queryResult; my @sidResult; while (@row = $sth->fetchrow_array) { push @queryResult, @row; push @sidResult, $row[0].","; $queryResult .= join("\t",@row) . "\n"; } # output arguments # if ($queryResult eq ""){$queryResult = "No result found";} return ($queryResult, @sidResult); $sth->finish(); $dbh->disconnect(); }

I get the following error message from our university server

DBD::CSV::st execute failed: Execution ERROR: No filename given at /usr/lib64/perl5/DBD/File.pm lin +e 565. called from runSQLQuery.pl at 11. at /usr/lib64/perl5/DBD/File.pm line 565. [for Statement "SELECT sid,genotype FROM newCsv.csv WHERE genotype = +'a'"] at runSQLQuery.pl line 32. DBD::CSV::st execute failed: Execution ERROR: No filename given at /usr/lib64/perl5/DBD/File.pm lin +e 565. called from runSQLQuery.pl at 11. at /usr/lib64/perl5/DBD/File.pm line 565. [for Statement "SELECT sid,genotype FROM newCsv.csv WHERE genotype = +'a'"] at runSQLQuery.pl line 32.

Could you please point out the error of my ways?

!!Fixed!!. Thank you, bretheren, for your wise counsel. The clue came from an anonymous brother who pointed out that there was no need for me to both specify the file extension name *.csv and also use the command f_ext => ".csv/r", When I did this I no longer received an error message, but I also got a nil return, which I new to be wrong.

Searching on stackoverflow, I found that in the act of cleaning up a and creating a csv file one can remove the DOS/Windows line ending which DBD::CSV assumes regardless of the platform the script is run on. Thanks to Grant McLean at http://stackoverflow.com/questions/2786741/dbdcsv-problem-with-file-name-extensions for this insight

The solution is to add the term csv_eol => "\n", as $dbh parameter.

Replies are listed 'Best First'.
Re: DBD::CSV::st execute failed:
by GrandFather (Saint) on May 27, 2016 at 22:23 UTC

    As an aside:

    ... return ($queryResult, @sidResult); $sth->finish(); $dbh->disconnect(); }

    is unusual. The last two statements will not be executed.

    Premature optimization is the root of all job security

      Thank you GrandFather

Re: DBD::CSV::st execute failed:
by Tux (Canon) on May 28, 2016 at 09:28 UTC

    If you use f_ext => ".csv/r", you explicitly tell the driver that the extension is required. If you add the /r, you should not add .csv to the table name. The driver will still be able to open your file, but it is not quaranteed anymore which file it opens: newCsv, newCsv.csv, or newCsv.csv.csv.

    Another issue is case sensitivity. On Windows newCsv will match against any casing. On Linux you might need to check if your file name matches.

    $ cat newCsv.csv foo,bar,baz 1,2,3 $ perl -MDP -MDBI -e'my$s=DBI->connect("dbi:CSV:",undef,undef,{f_ext=> +".csv/r"})->prepare("select * from newCsv");$s->execute;DDumper$s->fe +tchrow_hashref' { bar => 2, baz => 3, foo => 1 } $ perl -MDP -MDBI -e'my$s=DBI->connect("dbi:CSV:",undef,undef,{f_ext=> +".csv/r"})->prepare("select * from newCsv.csv");$s->execute;DDumper$s +->fetchrow_hashref' { bar => 2, baz => 3, foo => 1 } $ perl -MDP -MDBI -e'my$s=DBI->connect("dbi:CSV:",undef,undef,{f_ext=> +".csv/r"})->prepare("select * from newcsv");$s->execute;DDumper$s->fe +tchrow_hashref' DBD::CSV::st execute failed: Execution ERROR: Cannot open /tmp/ne.csv: No such file or directory (2 +) at /pro/lib/perl5/site_perl/5.24.0/x86_64-linux-thread-multi-ld/DBI +/DBD/SqlEngine.pm line 1624. . [for Statement "select * from newcsv"] at -e line 1. DBD::CSV::st fetchrow_hashref failed: Attempt to fetch row without a p +receding execute () call or from a non-SELECT statement [for Statemen +t "select * from newcsv"] at -e line 1. undef

    I see that the error message could use some improvement :)


    Enjoy, Have FUN! H.Merijn

      The wrong error message actually proved to be a bug in DBI, which I now fixed and pushed.


      Enjoy, Have FUN! H.Merijn

      Thank you, Tux. I have removed the file extension .csv, and I note your comments on case sensitivity - all table headings etc are lower case and the csv file is correctly cased - if that is the right expression - as newCsv.csv.

      Sadly, I still get the same error messages. Still seeking divine guidance from the Monastery!!

        It might be handy to post a part of the file, perhaps a head -n 20 (that is to say, the first 20 lines) so that experimentation is easier.

        (and the actual filename)

Re: DBD::CSV::st execute failed:
by Anonymous Monk on May 27, 2016 at 23:33 UTC
      haha a better path would be  path( __FILE__ )->realpath->parent->path('mycsvdb');
Re: DBD::CSV::st execute failed:
by Anonymous Monk on May 27, 2016 at 22:08 UTC
    What is the name of the file?

        Thank you. I have removed f_ext => ".csv/r", from the script. However, this just gives me "No result found" which I know to be wrong

        The perl script is runSQLQuery.pl. The csv file is newCsv.csv