0

below is the code

 #!/usr/bin/perl
 use warnings;
 use strict;
 use DBI;
 my $dbh = DBI->connect('dbi:DBM:sid=upr18;host=abd-up3db1',"user", "pass");
 my $sth = $dbh->prepare("SELECT count(*) FROM temp_table");
 $sth->execute();

While the connnect and prepare statements do notactually throw error and isee that the execute statement is erroring out. below is the error

DBD::DBM::st execute failed: Cannot open ./temp_table.lck: No such file or directory at /usr/perl5/vendor_perl/5.8.4/i86pc-solaris-64int/DBD/File.pm line 574. [for Statement "SELECT count(*) FROM temp_table"] at Test.pl line 8.

Any suggestions where i went wrong.

LearningCpp
  • 972
  • 12
  • 29

1 Answers1

5

It appears that you get this error (and, I agree it's not a particularly useful error) if you try to connect to a DBM file that doesn't exist.

In order for this code to work, you need to create a DBM file called temp_table.pag which contains the data that you want to use.

As always, it is a good idea to read the documentation of the module that you are trying to use. The DBD::DBM documentation includes a sample program that I had to adapt lightly in order to get it working:

#!/usr/bin/perl

use warnings;
use strict;
use feature 'say';

use DBI;

my $dbh = DBI->connect('dbi:DBM:');
$dbh->{RaiseError} = 1;
for my $sql( split /;\n+/,"
    CREATE TABLE user ( user_name TEXT, phone TEXT );
    INSERT INTO user VALUES ('Fred Bloggs','233-7777');
    INSERT INTO user VALUES ('Sanjay Patel','777-3333');
    INSERT INTO user VALUES ('Junk','xxx-xxxx');
    DELETE FROM user WHERE user_name = 'Junk';
    UPDATE user SET phone = '999-4444' WHERE user_name = 'Sanjay Patel';
    SELECT * FROM user
"){
    say $sql;
    my $sth = $dbh->prepare($sql);
    $sth->execute;
    # It was the "if" clause that I had to change.
    # Previously it was: if $sth->{NUM_OF_FIELDS}.
    # I wonder if the behaviour of NUM_OF_FIELDS has changed.
    $sth->dump_results if $sql =~ /\bselect\b/i;
}
$dbh->disconnect;

Having run this, I have files called user.pag and user.dir. I can then run a program that is very much like yours successfully.

#!/usr/bin/perl

use warnings;
use strict;

use DBI;

my $dbh = DBI->connect('dbi:DBM:');
my $sth = $dbh->prepare('SELECT user_name FROM user');
$sth->execute;
while (my $row = $sth->fetch) {
  print "$row->[0]\n";
}
$sth->execute();

Update: I also meant to add that reading the documentation will tell you which options are valid for DBD::DBM. It looks to me like sid and host aren't doing anything useful here. Also, username and password are unlikely to be necessary for file-based DBDs.

Update 2: Are you using the right database driver here? DBD::DBM is for accessing DBM files that sit on your local system. A DBM file is a really simple, single-table, file-based data file. It's not really a "database" as we would understand the term these days. It's very old technology and is rarely used these days.

Your comments below make it look like you're trying to connect to a real relational database system. In that case, DBD::DBM is completely the wrong database driver to use. You need the database driver that matches the system that you are using. Your use of the term "SID" makes me think that you're using Oracle - so you would need DBD::Oracle.

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • how to connect to db using sid,host,port,uname and password , am a bit confused as i dont see the uasge of these in documentation too, and you are 100% correct that sid,host,port dont really ad any value as per ths code, but i need them to connect to DB , i usually use those values via sqldeveloper and never used them in perl . and the tables i have specified in my code are very big tables in DB , though i am not sure if it has .pag and .dir files . please advice – LearningCpp Apr 07 '18 at 02:26
  • well, my question is how to connect to the db with the uname,pwd for accessing the table.in the above stmt we are creating a table and therefore can access it, what about the already available tables, i have around 100 different SID where i have to access, is this the right way . please suggest – LearningCpp Apr 07 '18 at 02:42
  • @LearningCpp: See the second update to my answer. I think you're on completely the wrong track here. – Dave Cross Apr 07 '18 at 07:02
  • Yeah I get it now , well I used this driver as oracle driver wasn’t available on my box . Thought this does the same . This seems to work only for file based DB . – LearningCpp Apr 07 '18 at 07:09
  • *I used this driver as oracle driver wasn’t available on my box* "I used a knife to eat this soup as a spoon wasn't available in my cutlery drawer." *Thought this does the same* Guessing at what things do isn't a good way to write code. Modules have documentation for a reason. *This seems to work only for file based DB* Yes. And a **specific type** of file-based database. – Dave Cross Apr 07 '18 at 07:13
  • It's very old technology and is rarely used these days. which ? The Relational DB or File based – LearningCpp Apr 07 '18 at 13:17
  • @LearningCpp: That sentence is at the end of a paragraph talking about DBM. So it's also talking about DBM. Which, as I've tried to make clear, is **one specfic type** of file-based database. – Dave Cross Apr 07 '18 at 17:17