Unable to run sample code from DBD::DBM on Strawberry Perl

J

jl_post

Dear Perl community,

Recently I installed DBD::DBM on my platform (Strawberry Perl on
Windows Vista). However, when I type "del user*" and run the
following program (that I found in "perldoc DBD::DBM):

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
"){
my $sth = $dbh->prepare($sql);
$sth->execute;
$sth->dump_results if $sth->{NUM_OF_FIELDS};
}
$dbh->disconnect;

I see:

Execution ERROR: Table 'user' already exists..
DBD::DBM::st execute failed:
Execution ERROR: Table 'user' already exists..
[for Statement "
CREATE TABLE user ( user_name TEXT, phone TEXT )"] at dbi_dbm.pl
line 14.
DBD::DBM::st execute failed:
Execution ERROR: Table 'user' already exists..
[for Statement "
CREATE TABLE user ( user_name TEXT, phone TEXT )"] at dbi_dbm.pl
line 14.

and I see three new zero-length files named "user.lck", "user.pag",
and "user.dir".

I decided to rerun the script (after "del user*") with the "$dbh-
{RaiseError} = 1;" line commented out, and I still get error
messages:

Execution ERROR: Cannot CREATE 'user.pag' because it already exists at
C:/strawb
erry/perl/site/lib/DBD/DBM.pm line 338.
DBD::DBM::st execute failed: Can't call method "column" on an
undefined value at
C:/strawberry/perl/site/lib/SQL/Statement/Term.pm line 190.
[for Statement " DELETE FROM user WHERE user_name = 'Junk'"] at
dbi_dbm.pl line 14.
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry
/perl/site/lib/DBD/File.pm at 446.
Execution ERROR:
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
called from dbi_dbm.pl at 14.
Execution ERROR:
Execution ERROR:
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
called from dbi_dbm.pl at 14.
undef, undef
undef, undef
undef, undef
3 rows

This time, the "user.pag" file has 1,024 bytes in it, and when I view
it in a hex editor, I see that it ends with this text: xxx-
xxxxJunk777-3333Sanjay Patel233-7777Fred Bloggs

So it looks like the "INSERT INTO" commands worked, but the
"UPDATE" and "SELECT" commands didn't work.

(For the record, I am deleting the user* files before I run the
script.)

I tried running this script on a Linux platform, and it worked fine
(with no errors). I'm only getting this error running this script on
my Windows platform (Strawberry Perl 5.10 on Windows Vista), and so
I'm wondering if anyone else on a similar platform is seeing the same
error I'm seeing.

For anyone who wants it, here are the first two lines of "perl -v":
This is perl, v5.10.0 built for MSWin32-x86-multi-thread
Copyright 1987-2007, Larry Wall

Is anyone else having trouble using DBD::DBM ?

Thanks.

-- Jean-Luc
 
S

Steve C

Dear Perl community,

Recently I installed DBD::DBM on my platform (Strawberry Perl on
Windows Vista). However, when I type "del user*" and run the
following program (that I found in "perldoc DBD::DBM):

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
"){
my $sth = $dbh->prepare($sql);
$sth->execute;
$sth->dump_results if $sth->{NUM_OF_FIELDS};
}
$dbh->disconnect;

I see:

Execution ERROR: Table 'user' already exists..
DBD::DBM::st execute failed:
Execution ERROR: Table 'user' already exists..
[for Statement "
CREATE TABLE user ( user_name TEXT, phone TEXT )"] at dbi_dbm.pl
line 14.
DBD::DBM::st execute failed:
Execution ERROR: Table 'user' already exists..
[for Statement "
CREATE TABLE user ( user_name TEXT, phone TEXT )"] at dbi_dbm.pl
line 14.

and I see three new zero-length files named "user.lck", "user.pag",
and "user.dir".

These are not perl errors, they are errors in your understanding of how a
database works. You can't create a new table if a table already exists with
that name. If you don't want the old one, you need to DROP it first.

I decided to rerun the script (after "del user*") with the "$dbh-
{RaiseError} = 1;" line commented out, and I still get error
messages:

Execution ERROR: Cannot CREATE 'user.pag' because it already exists at
C:/strawb
erry/perl/site/lib/DBD/DBM.pm line 338.
DBD::DBM::st execute failed: Can't call method "column" on an
undefined value at
C:/strawberry/perl/site/lib/SQL/Statement/Term.pm line 190.
[for Statement " DELETE FROM user WHERE user_name = 'Junk'"] at
dbi_dbm.pl line 14.
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry
/perl/site/lib/DBD/File.pm at 446.
Execution ERROR:
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
called from dbi_dbm.pl at 14.
Execution ERROR:
Execution ERROR:
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
called from dbi_dbm.pl at 14.
undef, undef
undef, undef
undef, undef
3 rows

This time, the "user.pag" file has 1,024 bytes in it, and when I view
it in a hex editor, I see that it ends with this text: xxx-
xxxxJunk777-3333Sanjay Patel233-7777Fred Bloggs

So it looks like the "INSERT INTO" commands worked, but the
"UPDATE" and "SELECT" commands didn't work.

(For the record, I am deleting the user* files before I run the
script.)


Why do you think deleting the files is the right thing to do?
If you want to use a database, learn how first. Don't just guess.
 
S

sln

Dear Perl community,

Recently I installed DBD::DBM on my platform (Strawberry Perl on
Windows Vista). However, when I type "del user*" and run the
following program (that I found in "perldoc DBD::DBM):
[snip]
I tried running this script on a Linux platform, and it worked fine
(with no errors). I'm only getting this error running this script on
my Windows platform (Strawberry Perl 5.10 on Windows Vista), and so
I'm wondering if anyone else on a similar platform is seeing the same
error I'm seeing.

For anyone who wants it, here are the first two lines of "perl -v":
This is perl, v5.10.0 built for MSWin32-x86-multi-thread
Copyright 1987-2007, Larry Wall

Is anyone else having trouble using DBD::DBM ?

Thanks.

-- Jean-Luc

I suspect its either a version problem, bundle problem,
Perl distribution problem, etc..

It works as expected on my AS Perl 5.10.0, XP os.
Below is run info, as well as info from installed
packages -DBI, from ppm (graphic interface).

-sln
-------------------------
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

c:\temp>perl kk.pl
'Fred Bloggs', '233-7777'
'Sanjay Patel', '777-3333'
2 rows

c:\temp>perl kk.pl

Execution ERROR: Cannot CREATE '.\user.pag' because it already exists at C:/Perl
/lib/DBD/DBM.pm line 338.
..

DBD::DBM::st execute failed:
Execution ERROR: Cannot CREATE '.\user.pag' because it already exists at C:/Perl
/lib/DBD/DBM.pm line 338.
..

[for Statement "
CREATE TABLE user ( user_name TEXT, phone TEXT )"] at kk.pl line 15.
DBD::DBM::st execute failed:
Execution ERROR: Cannot CREATE '.\user.pag' because it already exists at C:/Perl
/lib/DBD/DBM.pm line 338.
..

[for Statement "
CREATE TABLE user ( user_name TEXT, phone TEXT )"] at kk.pl line 15.

c:\temp>del user*

c:\temp>perl kk.pl
'Fred Bloggs', '233-7777'
'Sanjay Patel', '777-3333'
2 rows

c:\temp>del user*

c:\temp>perl kk.pl
'Fred Bloggs', '233-7777'
'Sanjay Patel', '777-3333'
2 rows

c:\temp>

-----------------------------------------
DBI
Database independent interface for Perl
Version: 1.607
Released: 2008-07-30
Author: Tim Bunce <[email protected]>
CPAN: http://search.cpan.org/dist/DBI-1.607/

Installed files:
C:/Perl/bin/dbilogstrip
C:/Perl/bin/dbilogstrip.bat
C:/Perl/bin/dbiprof
C:/Perl/bin/dbiprof.bat
C:/Perl/bin/dbiproxy
C:/Perl/bin/dbiproxy.bat
C:/Perl/lib/Bundle/DBI.pm
C:/Perl/lib/DBD/DBM.pm
C:/Perl/lib/DBD/ExampleP.pm
C:/Perl/lib/DBD/File.pm
C:/Perl/lib/DBD/Gofer.pm
C:/Perl/lib/DBD/Gofer/Policy/Base.pm
C:/Perl/lib/DBD/Gofer/Policy/classic.pm
C:/Perl/lib/DBD/Gofer/Policy/pedantic.pm
C:/Perl/lib/DBD/Gofer/Policy/rush.pm
C:/Perl/lib/DBD/Gofer/Transport/Base.pm
C:/Perl/lib/DBD/Gofer/Transport/null.pm
C:/Perl/lib/DBD/Gofer/Transport/pipeone.pm
C:/Perl/lib/DBD/Gofer/Transport/stream.pm
C:/Perl/lib/DBD/NullP.pm
C:/Perl/lib/DBD/Proxy.pm
C:/Perl/lib/DBD/Sponge.pm
C:/Perl/lib/DBI.pm
C:/Perl/lib/DBI/Changes.pm
C:/Perl/lib/DBI/Const/GetInfo/ANSI.pm
C:/Perl/lib/DBI/Const/GetInfo/ODBC.pm
C:/Perl/lib/DBI/Const/GetInfoReturn.pm
C:/Perl/lib/DBI/Const/GetInfoType.pm
C:/Perl/lib/DBI/DBD.pm
C:/Perl/lib/DBI/DBD/Metadata.pm
C:/Perl/lib/DBI/FAQ.pm
C:/Perl/lib/DBI/Gofer/Execute.pm
C:/Perl/lib/DBI/Gofer/Request.pm
C:/Perl/lib/DBI/Gofer/Response.pm
C:/Perl/lib/DBI/Gofer/Serializer/Base.pm
C:/Perl/lib/DBI/Gofer/Serializer/DataDumper.pm
C:/Perl/lib/DBI/Gofer/Serializer/Storable.pm
C:/Perl/lib/DBI/Gofer/Transport/Base.pm
C:/Perl/lib/DBI/Gofer/Transport/pipeone.pm
C:/Perl/lib/DBI/Gofer/Transport/stream.pm
C:/Perl/lib/DBI/Profile.pm
C:/Perl/lib/DBI/ProfileData.pm
C:/Perl/lib/DBI/ProfileDumper.pm
C:/Perl/lib/DBI/ProfileDumper/Apache.pm
C:/Perl/lib/DBI/ProfileSubs.pm
C:/Perl/lib/DBI/ProxyServer.pm
C:/Perl/lib/DBI/PurePerl.pm
C:/Perl/lib/DBI/Roadmap.pm
C:/Perl/lib/DBI/SQL/Nano.pm
C:/Perl/lib/DBI/Util/CacheMemory.pm
C:/Perl/lib/DBI/Util/_accessor.pm
C:/Perl/lib/DBI/W32ODBC.pm
C:/Perl/lib/Roadmap.pod
C:/Perl/lib/TASKS.pod
C:/Perl/lib/Win32/DBIODBC.pm
C:/Perl/lib/auto/DBI/.packlist
C:/Perl/lib/auto/DBI/DBI.bs
C:/Perl/lib/auto/DBI/DBI.dll
C:/Perl/lib/auto/DBI/DBI.exp
C:/Perl/lib/auto/DBI/DBI.lib
C:/Perl/lib/auto/DBI/DBIXS.h
C:/Perl/lib/auto/DBI/Driver.xst
C:/Perl/lib/auto/DBI/Driver_xst.h
C:/Perl/lib/auto/DBI/dbd_xsh.h
C:/Perl/lib/auto/DBI/dbi_sql.h
C:/Perl/lib/auto/DBI/dbipport.h
C:/Perl/lib/auto/DBI/dbivport.h
C:/Perl/lib/auto/DBI/dbixs_rev.h
C:/Perl/lib/dbixs_rev.pl
 
J

jl_post

These are not perl errors, they are errors in your
understanding of how a database works.  You can't
create a new table if a table already exists with
that name.  If you don't want the old one, you need
to DROP it first.


I understand that. But the first time I run the script, there is
no database by the name 'user'. Therefore, it shouldn't be
complaining that the 'user' table already exists.

In fact, just to make sure, I went ahead and added "DROP TABLE
user;" to my script, just like you said (I also commented out the
'RaiseError' line), making it look like this:

use DBI;
my $dbh = DBI->connect('dbi:DBM:');
# $dbh->{RaiseError} = 1;
for my $sql( split /;\n+/,"
DROP TABLE user;
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
"){
my $sth = $dbh->prepare($sql);
$sth->execute;
$sth->dump_results if $sth->{NUM_OF_FIELDS};
}
$dbh->disconnect;

Now when I run the script, I see:

Execution ERROR: Table 'user' already exists..
DBD::DBM::st execute failed: Can't call method "column" on an
undefined value at C:/strawberry/perl/site/lib/SQL/Statement/Term.pm
line 190.
[for Statement " DELETE FROM user WHERE user_name = 'Junk'"] at
dbi_dbm.pl line 15.
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
Execution ERROR:
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
called from dbi_dbm.pl at 15.
Execution ERROR:
Execution ERROR:
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
called from dbi_dbm.pl at 15.
..
undef, undef
undef, undef
undef, undef
3 rows

Notice that the Execution ERROR stating that table 'user' already
exists is still reported. I don't think it's my understanding that's
in error here. (Especially since the example script (as shown in
"perldoc DBD::DBM") worked just fine for time the first time I ran it
in Linux.)

(What I'm trying to say is, if "DROP TABLE user;" was required to
run the example the first time, then the perldocs would have given a
faulty script by not including that line.)

Why do you think deleting the files is the right thing to do?
If you want to use a database, learn how first. Don't just guess.

Because when I ran the script it created those three new files,
each beginning with "user". That's consistent with what I know of DBM
databases, in that the DBM data is stored in files beginning with the
database name. (At least, that's the behavior I've seen with all the
DBM databases I've tinkered with.)

But if you have a concrete example that contradicts mine, please
show it to me. I mentioned that I deleted the "user*" files to
indicate that I shouldn't have any DBM files hanging around that begin
with "user". But if the table already exists because it's stored in
some other file (thus proving my assumption false), I'd definitely
like to know.

The fact that I could see the inserted data (with a hex editor) in
the "user.pag" file seems to reinforce my assumption.

But if you can prove my assumption wrong (which is that the
database data is held in the "user*" files), please do so! I would
appreciate having that false assumption corrected (if it is indeed
false).

Cheers,

-- Jean-Luc
 
S

Steve C

These are not perl errors, they are errors in your
understanding of how a database works. You can't
create a new table if a table already exists with
that name. If you don't want the old one, you need
to DROP it first.


I understand that. But the first time I run the script, there is
no database by the name 'user'. Therefore, it shouldn't be
complaining that the 'user' table already exists.

In fact, just to make sure, I went ahead and added "DROP TABLE
user;" to my script, just like you said (I also commented out the
'RaiseError' line), making it look like this:

use DBI;
my $dbh = DBI->connect('dbi:DBM:');
# $dbh->{RaiseError} = 1;
for my $sql( split /;\n+/,"
DROP TABLE user;
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
"){
my $sth = $dbh->prepare($sql);
$sth->execute;
$sth->dump_results if $sth->{NUM_OF_FIELDS};
}
$dbh->disconnect;

Now when I run the script, I see:

Execution ERROR: Table 'user' already exists..
DBD::DBM::st execute failed: Can't call method "column" on an
undefined value at C:/strawberry/perl/site/lib/SQL/Statement/Term.pm
line 190.
[for Statement " DELETE FROM user WHERE user_name = 'Junk'"] at
dbi_dbm.pl line 15.
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
Execution ERROR:
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
called from dbi_dbm.pl at 15.
Execution ERROR:
Execution ERROR:
Execution ERROR: Column 'phone' not known in any table called from C:/
strawberry/perl/site/lib/DBD/File.pm at 446.
called from dbi_dbm.pl at 15.
.
undef, undef
undef, undef
undef, undef
3 rows

Notice that the Execution ERROR stating that table 'user' already
exists is still reported. I don't think it's my understanding that's
in error here. (Especially since the example script (as shown in
"perldoc DBD::DBM") worked just fine for time the first time I ran it
in Linux.)

(What I'm trying to say is, if "DROP TABLE user;" was required to
run the example the first time, then the perldocs would have given a
faulty script by not including that line.)

Why do you think deleting the files is the right thing to do?
If you want to use a database, learn how first. Don't just guess.

Because when I ran the script it created those three new files,
each beginning with "user". That's consistent with what I know of DBM
databases, in that the DBM data is stored in files beginning with the
database name. (At least, that's the behavior I've seen with all the
DBM databases I've tinkered with.)

But if you have a concrete example that contradicts mine, please
show it to me. I mentioned that I deleted the "user*" files to
indicate that I shouldn't have any DBM files hanging around that begin
with "user". But if the table already exists because it's stored in
some other file (thus proving my assumption false), I'd definitely
like to know.

The fact that I could see the inserted data (with a hex editor) in
the "user.pag" file seems to reinforce my assumption.

But if you can prove my assumption wrong (which is that the
database data is held in the "user*" files), please do so! I would
appreciate having that false assumption corrected (if it is indeed
false).

I didn't say the table wasn't stored in those files, I said that
deleting the files is not the appropriate way to manipulate a
database.

dbm refers to a number of different database methods depending
on the libraries installed on your system, so you can't expect
different system to behave the same way when you do something outside
of the normal methods.

You should be checking the return values from both connect and from
execute at each step, regardless of what the example code says.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top