Load data infile mysql statement in perl error handling - mysql

Below is my perl code
I referred to the following link http://www.tol.it/doc/MySQL/chapter6.html. If there is a better please post.
use Mysql;
my $db = Mysql->connect($mysqlhost, $mysqlDB, $mysqlUser, $mysqlPassword);
$db->selectdb("$mysqlDB");
my $loadQuery="LOAD DATA INFILE '$filename' INTO TABLE $pageURLTable FIELDS TERMINATED BY '\\t' LINES TERMINATED BY '\\n'";
print "Executing $loadQuery";
my $loadresult=$db->query($loadQuery);
if(!$loadresult){
print "Error: MySQl Load failed.System error message:$!.";
return -1;
}
print "Info:".$loadresult->info"; ## this raises error MySQL::Statement info not loadable;
What is wrong ?
Can you suggest a better way of coding this so that Load data file errors are better captured?
Thanks,
Neetesh

Try to use ->do method instead of ->query.
Make sure that Load Data Inline is enabled in your database.
If above don't work, you can use system(mysql -e "LOAD DATA INFILE...")

I generally use DBI recipes. "executing sql statement" I like to do something like $rows = $sth->execute(); Gives affected rows by last statement, and if rows >0 after loading csv files I'know that I've successfully loaded data in database.
my $sth = $dbh->prepare($sql)
or die "Can't prepare SQL statement: ", $dbh->errstr(), "\n";
$rows = $sth->execute();
if ($rows>0)
{
print "Loaded $rows rows\n" if ($Debug);
}
else {
print "Can't execute SQL statement: ", $sth->errstr(), "\n";
}

Related

Insert data from text file (saved in my PC) to tables MySQL

I have one problem, I am totally beginner and I would like Insert or convert data, which I have on my PC like txt file to my tables created by Mysql language. Is it possible?
Table has same columns like txt file.
Thank you so much
You can write direct sql query Like this
LOAD DATA INFILE 'C://path/to/yourfilename.txt'
INTO TABLE 'database_name'.'table_name'
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n\r'
(column1,column2)
Here i assumed that your fields are terminated by semi column.
for line termination Character and Escape sequence you can take reference from this thread
http://dev.mysql.com/doc/refman/5.1/en/load-data.html
You can write a simple program that loops through the content of the file and inserts the data into the database. Here is something to get you started.
This simply inserts the data you have put in the PHP code.
What you will want to do is to open a file and insert the data from it
mysql_connect('localhost', 'user', 'pass') or die(mysql_error());
mysql_select_db('db_name') or die(mysql_error());
$lines = file('company.txt');
$company_names = ""; $insert_string
= "INSERT INTO company(company_name) VALUES"; $counter = 0; $maxsize = count($lines);
foreach($lines as $line => $company) {
$insert_string .= "('".$company."')"; $counter++; if($counter <
$maxsize) { $insert_string .= ","; }//if }//foreach
mysql_query($insert_string) or die(mysql_error());

DBD::mysql fetchrow_array failed: fetch() without execute()?

I am getting the error for the following code:
#!C:/usr/bin/perl -w
use CGI;
use strict;
use DBI();
use CGI::Carp qw(fatalsToBrowser);
print "content-type: text/html; charset=iso-8859-1\n\n";
my $q=new CGI;
my $ename=$q->param('ename');
my $email=$q->param('email');
print $q->header;
print "<br>$ename<br>";
#connect to database.
my $dbh = DBI->connect("DBI:mysql:database=test;host=localhost","root","mukesh",
{'RaiseError' => 1});
eval {$dbh->do("CREATE TABLE IF NOT EXISTS emp (ename VARCHAR(20), email VARCHAR(50))")};
print "<br>creating table emp failed: $#<br>" if $#;
my $sql="INSERT INTO emp(ename,email) values('$ename','$email')";
my $sth = $dbh->prepare($sql) or die "Can't prepare $sql:$dbh->errstrn";
#pass sql query to database handle
my $rv = $sth->execute() or die "can't execute the query: $sth->errstrn";
my #row;
while (#row = $sth->fetchrow_array) {
print join(", ",#row);
}
$sth->finish();
$dbh->disconnect();
if ($rv==1){
print "<br>Record has been successfully updated !!!<br>";
}else{
print "<br>Error!!while inserting record<br>";
exit;
}
Please suggest.what is the problem.
it works fine if i remove this piece of code.
my #row;
while (#row = $sth->fetchrow_array) {
print join(", ",#row);
}
You're trying to use the common SELECT cycle in DBI - prepare, execute, fetch - for a non-select query (INSERT in your case). What you probably should do instead is check the result of execute directly. Quoting the doc:
For a non-SELECT statement, execute returns the number of rows
affected, if known. If no rows were affected, then execute returns
"0E0", which Perl will treat as 0 but will regard as true. Note that
it is not an error for no rows to be affected by a statement. If the
number of rows affected is not known, then execute returns -1.

Update MySQL within Perl loop failing (fetchrow_array)

I've created a Perl script which is meant to loop through an array (a shortlist of customers who meet certain criteria), execute an external command using system() , then update a field within each row once the operation has completed.
It works on the first record (ie external command executes, customer record updates), however when it gets to the second record I receive this error:
DBD::mysql::st fetchrow_array failed: fetch() without execute() at customer_update.pl
Through some googling I added the $sth->finish(); command, however whether I include it or not (either inside the loop as shown, or straight afterward) I still get the same error.
Can anyone shed any light for me as to what I am doing wrong here?
Here's an extract:
# PERL MYSQL CONNECT()
$dbh = DBI->connect('dbi:mysql:signups', $user, $pw)
or die "Connection Error: $DBI::errstr\n";
# DEFINE A MySQL QUERY
$myquery = "SELECT * FROM accounts WHERE field3 = false";
$sth = $dbh->prepare($myquery);
# EXECUTE THE QUERY
$sth->execute
or die "SQL Error: $DBI::errstr\n";
#records = $sth->rows;
print "Amount of new customers: #records\n\n";
while ( my ($field1, $field2, $field3) = $sth->fetchrow_array() ) {
#execute external command via system();
$update_customer_status = "UPDATE accounts SET field3=true WHERE id=$id";
$sth = $dbh->prepare($update_customer_status);
$sth->execute
or die "SQL Error: $DBI::errstr\n";
print "Customer record modified & MySQL updated accordingly\n\n";
$sth->finish();
}
Building a SQL statement with variables and then prepare()ing it defeats the purpose of the prepare. You should build the SQL statement with a placeholder ? instead of $id, prepare() it, and then execute($id) it. As it is, you are leaving yourself open to SQL injection attacks.
Also, it seems that you are not using the warnings and strict pragmas. These two lines should be at the top of every program you write:
use warnings;
use strict;
They will save you much heartache and frustration in the future.
In your loop, you overwrite the handle over from which you are fetching. Use a different variable. (Changing $sth = ...; to my $sth = ...; will do.) While we're at it, let's move the prepare out of the loop.
my $sth_get = $dbh->prepare("SELECT * FROM accounts WHERE field3 = false");
my $sth_upd = $dbh->prepare("UPDATE accounts SET field3=true WHERE id = ?");
$sth_get->execute();
while ( my ($field1, $field2, $field3) = $sth_get->fetchrow_array() ) {
...
$sth_upd->execute($id);
}
You are stomping on your $sth variable when you execute this line ...
$sth = $dbh->prepare($update_customer_status);
Why not save off the result of $sth->fetchrow_array() to an array variable.
Something like ...
my #select_results_AoA = $sth->fetchrow_array();
... and then iterate over the array ...
for my #row ( #select_resilts_AoA ) {
... instead of ...
while ( my ($field1, $field2, $field3) = $sth->fetchrow_array() ) {

MySQL error in Perl ( Errorcode 2)

I am complete newbie in Perl. I have this little sub
sub processOpen{
my($filename, $mdbh)=#_;
my($qr, $query);
# parse filename to get the date extension only
# we will import the data into the table with this extension
# /home//logs/open.v7.20120710_2213.log
my(#fileparts) = split(/\./, $filename);
my(#filedateparts) = split(/_/, $fileparts[2]);
my($tableext) = $filedateparts[0];
$query = "LOAD DATA INFILE '" . $filename . "' INTO TABLE open_" . $tableext . " FIELDS TERMINATED BY '||' LINES TERMINATED BY '\n'
(open_datetime, open_date, period,tag_id)";
$qr = $$mdbh->prepare($query);
$qr->execute(); # causes error (see below)
$qr->finish();
}
And I'm getting the following error:
DBD::mysql::st execute failed: Can't get stat of '/home/logs/open..v7.20120710_2213.log' (Errcode: 2) at /home/thisfile.pm line 32.
Line 32 is the $qr->execute();
Error Code 2 is most likely "File not found".
Does your file exist? Note that if you are running the perl on a separate host from the MySQL database, the file must be on the database host, not the client host.

Parameterizing file name in MYSQL LOAD DATA INFILE

Is there a way to dynamically specify a file name in the LOAD DATA INFILE? Can it be parameterized like for instance (syntax may be incorrect) LOAD DATA INFILE '$filename'?
A citation from MySQL documentation:
The LOAD DATA INFILE statement reads rows from a text file into a table at a very high speed. The file name must be given as a literal string.
That means that it can not be a parameter of a prepared statement. But no one forbids to make the string interpolation while the statement is just a string in your PHP code.
Unfortunately, this feature is not yet supported in MySQL and is currently listed as bug/feature request #39115 http://bugs.mysql.com/bug.php?id=39115
Or you can make a temporary copy of the file (BATCH example):
LOAD_DATA.bat
COPY %1 TempFileToLoad.csv
mysql --user=myuser --password=mypass MyDatabase < ScriptLoadMyDatabase.sql
DEL TempFileToLoad.csv
the SQL (for info) :
ScriptLoadMyDatabase.sql
load data infile 'TempFileToLoad.csv' IGNORE
into table tLoad
FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"'
lines terminated by '\r\n'
IGNORE 1 LINES
(#DateCrea, NomClient, PrenomClient, TypeMvt, #Montant, NumeroClient)
set DateCrea = str_to_date(#DateCrea, '%Y-%m-%d'), Montant = (round(#Montant / 1000)*2) ;
And finished to put a link to the BAT file in SendTo windows folder.
If you're asking if it can be used in a script; you can do some thing like this with php:
<?php
$mysqli = new mysqli("host", "user", "pwd", "db");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$sql = "CREATE TABLE number1 (id INT PRIMARY KEY auto_increment,data TEXT)";
if ($result = $mysqli->query($sql)) {
} else {
printf("<br>%s",$mysqli->error);
}
$host = $_SERVER['HTTP_HOST'];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$filename = "data.csv";
$sql = "LOAD DATA LOCAL INFILE '$host$uri$filename' INTO TABLE number1";
if ($result = $mysqli->query($sql)) {
} else {
printf("<br>%s",$mysqli->error);
}
// Close the DB connection
$mysqli->close();
exit;
%>
If the file is in the same folder as the script just use $filename a instead of $host$uri$filename. I put this together quick from a couple scripts I'm using, sorry if it doesn't work without debug, but it should be pretty close. It requires mysqli.