in reply to Updating or Inserting a database from a txt file
Somewhat scared to enter this heated conversation, I'll try not to leave too large a footprint.
My suggestion is to clean it up like this:
my $dbh = DBI->connect('DBI:mysql:nikos_db', 'root', 'censored') or {R
+aiseError=>1};
my $rep = $dbh->prepare( "REPLACE INTO `games` (`gamename`, `gamedesc`
+, `gamecounter`) VALUES (?, ?, ?)" );
open (FILE, "<../data/games/descriptions.txt") or die $!;
while (<FILE>) {
chomp;
$rep->execute( split(/\t/, $_, 2) , 0 ) or print $dbh->errstr;
}
close (FILE);
$rep->finish;
$dbh->disconnect;
Since the insert would fail on a duplicate, I assume you already have a primary column determined, so a replace would seem to be the best - it almost identically follows insert syntax (at least in MySQL, which, I have to admit, is the only SQL db I've ever used). Hope this helps, -Adam
Re^2: Updating or Inserting a database from a txt file
by Nik (Initiate) on May 11, 2005 at 07:11 UTC
|
I wated to etst your script which seem very slick but i cant create a primary key.
i am tryign this:
$dbh->do( "CREATE TABLE games (gamename text, gamedesc text, gamecount
+er int, primary key(gamename))" );
Also can you please tell me what went wrong with my aproach even though i dont use a primary key? Here is the code!
my (@row, $gamename, $gamedesc, $gamecount);
my $select = $dbh->prepare( "SELECT * FROM games WHERE gamename=?" );
my $insert = $dbh->prepare( "INSERT INTO games (gamename, gamedesc, ga
+mecounter) VALUES (?, ?, ?)" );
my $update = $dbh->prepare( "UPDATE games SET gamedesc=?, gamecount=?+
+1 where gamename=?" );
open (FILE, "<../data/games/descriptions.txt") or die $!;
while (<FILE>) {
chomp;
($gamename, $gamedesc) = split /\t/;
$select->execute( $gamename );
if ($select->rows) {
$update->execute( $gamedesc, $gamecount, $gamename );
}
else {
$insert->execute( $gamename, $gamedesc, 0 );
}
}
close (FILE);
| [reply] [d/l] [select] |
|
Hey Nik,
Sorry for taking so long to reply.
To create a table, try doing this:
$dbh->do("CREATE TABLE `games` (`gamename` TEXT, `gamedesc` TEXT, `gam
+ecount` TEXT );");
Then, create a unique index on the table - the 200 is a length that you can modify if you want.
$dbh->do("ALTER TABLE `games` ADD UNIQUE `UNQINDX` ( `gamename` ( 200
+) )");
You should now successfully be able to use REPLACE on your table.
Taking a look at your code...
my (@row, $gamename, $gamedesc, $gamecount);
# selecting count(*) will run faster
my $select = $dbh->prepare( "SELECT count(*) FROM `games` WHERE `gamen
+ame`=?" );
# column `gamecount` was labeled as `gamecounter`
my $insert = $dbh->prepare( "INSERT INTO `games` (`gamename`, `gamedes
+c`, `gamecount`) VALUES (?, ?, ?)" );
my $update = $dbh->prepare( "UPDATE games SET gamedesc=?, gamecount=?
+where gamename=?" );
open (FILE, "<../data/games/descriptions.txt") or die $!;
while (<FILE>) {
chomp;
($gamename, $gamedesc) = split /\t/;
$select->execute( $gamename );
if ($select->fetchrow_array) {
# WARNING: $gamecount isn't defined!
$update->execute( $gamedesc, $gamecount, $gamename );
}
else {
$insert->execute( $gamename, $gamedesc, 0 );
}
}
close (FILE);
I'm a bit tired, but I hope this helps! Note my comments within the code.
The error in your message below indicates that the execute method isn't receiving the correct number of variables. Check to see that the file is tabbed correctly.
Best, -Adam | [reply] [d/l] [select] |
|
Thanks Adam but actually i have quit tryign to do it with my way and i decided to do it with your way since it is more straighforward and less lines of code: Now the code is like this:
#=======================LOADING THE .TXT TO THE DATABASE==============
+==========
my $replace = $dbh->prepare( "REPLACE INTO games (gamename, gamedesc,
+gamecounter) VALUES (?, ?, ?)" );
open (FILE, "<../data/games/descriptions.txt") or die $!;
while (<FILE>) {
chomp;
if (length) {
$replace->execute( split(/\t/, $_, 2), 0 ) or print $dbh->errs
+tr;
}
}
close (FILE);
But the records never get updated and if i delete a row on the txt file but the insertion of a new row or an edit of an existing one work ok :-)
Also after this code i ahve this:
if( param() )
{
$dbh->do( "UPDATE games SET gamecounter=gamecounter+1 WHERE gamena
+me='$gamename'" );
$dbh->do( "UPDATE guestlog SET passage='$gamename' WHERE host='$ho
+st'" );
$sth = $dbh->prepare( "SELECT * FROM games WHERE gamename=?" );
$sth->execute( $gamename );
$row = $sth->fetchrow_hashref;
print span( {class=>'lime'}, "Είσαι ο $row->{gamecounter} ος πο
+υ κατεβάζει το $row->{gamename} !!" ), br;
print span( {class=>'yellow'}, "Ελπίζω να σου αρέσει και να σου φ
+ανεί χρήσιμο!" );
print p( {-align=>'center'}, a( {href=>'index.pl'}, img {src=>'.
+./data/images/back.gif'} ));
print "<script language='Javascript'>location.href=/data/games/$ga
+mename.rar</script>";
}
which is supposed to print a message when a user hits a game button to
+ be download and show the user what he choosed to downlaoded and how
+many time it was in general downloaded but it doesnt.
| [reply] [d/l] [select] |
|
I had some small errors. Now the script is like this:
my ($gamename, $gamedesc, $gamecount);
my $select = $dbh->prepare( "SELECT count(*) FROM games WHERE gamename
+=?" );
my $insert = $dbh->prepare( "INSERT INTO games (gamename, gamedesc, ga
+mecounter) VALUES (?, ?, ?)" );
my $update = $dbh->prepare( "UPDATE games SET gamedesc=?, gamecount=?+
+1 where gamename=?" );
open (FILE, "<../data/games/descriptions.txt") or die $!;
while (<FILE>) {
chomp;
($gamename, $gamedesc) = split /\t/;
if ( $select->execute($gamename) ) {
$update->execute( $gamedesc, $gamecount, $gamename );
}
else {
$insert->execute( $gamename, $gamedesc, 0 );
}
}
close (FILE);
When it comes to updating it alwasy about the last game of the txt file and never the rest of them?
I cant see why! | [reply] [d/l] |
|
$select->execute($gamename);
my($rows) = $select->fetchrow_array; # first row
$select->finish; # premature abort: no more rows
if($rows) { # found
$update->execute( $gamedesc, $gamecount, $gamename );
}
else {
$insert->execute( $gamename, $gamedesc, 0 );
}
The finish tells DBI and the DB you no longer need this instance of the statement handle query. You normally have to call this after a SELECT query where you don't try to deplete the statement handle, fetching rows, thus until it returns undef.
BTW untested, I hope I got it right! :) | [reply] [d/l] [select] |
|
Adams aproach is better than mines and i think ill follow it but iam getting the following errors:
called with 1 bind variables when 3 are neededcalled with 1 bind varia
+bles when 3 are neededcalled with 1 bind variables when 3 are neededc
+alled with 1 bind variables when 3 are neededcalled with 1 bind varia
+bles when 3 are neededcalled with 1 bind variables when 3 are neededc
+alled with 1 bind variables when 3 are neededcalled with 1 bind varia
+bles when 3 are neededcalled with 1 bind variables when 3 are neededc
+alled with 1 bind variables when 3 are neededcalled with 1 bind varia
+bles when 3 are neededcalled with 1 bind variables when 3 are neededc
+alled with 1 bind variables when 3 are neededcalled with 1 bind varia
+bles when 3 are neededcalled with 1 bind variables when 3 are neededc
+alled with 1 bind variables when 3 are neededcalled with 1 bind varia
+bles when 3 are neededcalled with 1 bin
Which i dont understand.... | [reply] [d/l] |
|
|