perl array search on mysql results - mysql

I have a database which contains mobile numbers. How do I write perl script which get all of numbers into array & check new number already exist or not in that array?
Create Table:
CREATE TABLE consumeruser (
ConsumerId int(10) NOT NULL AUTO_INCREMENT,
ConsumerName varchar(45) DEFAULT NULL,
ConsumerMobNo varchar(10) DEFAULT NULL,
PRIMARY KEY (ConsumerId)
) ENGINE=InnoDB AUTO_INCREMENT=4494 DEFAULT CHARSET=latin1
Script :
#!/usr/bin/perl -w
use strict;
use warnings qw(all);
use DBI;
use Getopt::Long;
use Pod::Usage;
use Text::CSV_XS;
my $username = 'root'; # set your MySQL username
my $password = 'xxxx'; # set your MySQL password
my $database = 'app'; # set your MySQL database name
my $server = 'localhost'; # set your server hostname (probably localhost)
my $dbh = DBI->connect( "DBI:mysql:$database;host=$server", $username, $password )
|| die "Could not connect to database: $DBI::errstr";
my $CustomerMobileNumber = 9999999;
my #MobileNumbers;
my $mobileNumberQuery = "select ConsumerMobNo from consumeruser";
my $sth = $dbh->prepare($mobileNumberQuery);
$sth->execute();
while ( my #row = $sth->fetchrow_array() ) {
push #MobileNumbers, $row;
if (/test for is present/) {
#9999999 found in array;
} else {
#9999999 not found in array;
}
}

You can ask the database to search for the number:
my $mobileNumberQuery = "SELECT 1 FROM consumeruser WHERE ConsumerMobNo = ?";
my $sth = $dbh->prepare($mobileNumberQuery);
$sth->execute(9999999);
if ($sth->fetchrow_array) {
print "Found.\n"
} else {
print "Not found.\n";
}

Related

auto_increment not setting value for primary key?

I'm baffled, when I use the terminal (mysql) and insert into username,account_password columns, user_id AUTO_INCREMENTS just as it should.
my table:
CREATE TABLE users (
user_id int NOT NULL AUTO_INCREMENT,
user_type VARCHAR(20) NULL,
creation_date TIMESTAMP NOT NULL,
username VARCHAR(100) NOT NULL,
account_password VARCHAR(255) NOT NULL,
PRIMARY KEY (user_id)
);
yet when I use this script:
use strict;
use warnings FATAL => 'all';# good for debugging, FATAL kills program so warnings are more identifiable
use CGI qw/:standard/;
use CGI::Carp qw(fatalsToBrowser); # good for debugging, sends info to browser
use DBI;
use DBD::mysql;
use Digest::SHA qw(sha256);
print header, start_html;
my $fName = param('firstName');
my $lName = param('lastName');
my $compName = param('compName');
my $email = param('email');
my $pswrd = param('password');
my $cnfPswrd = param('confPassword');
my $encpswrd = "";
#check passwords match, if not display error, and exit script
if ($pswrd eq $cnfPswrd) {
$encpswrd = sha256($pswrd);
} else {
print "Passwords did not match! refresh form!";
exit;
}
#database credentials, to be changed accordingly
my $database = "intsystest";
my $host = "localhost";
my $user = "root";
my $pw = "password";
my $dsn = "dbi:mysql:$database:localhost:3306";
#connect to database
my $dbh = DBI->connect($dsn, $user, $pw,
{ RaiseError => 1 }) or die "unable to connect:$DBI::errstr\n"; # <- this line good for debugging
#create, prepare, execute query, disconnect from DB
my $personsQuery = "INSERT INTO persons (first_name, last_name) VALUES (?,?)";
my $compQuery = "INSERT INTO company (company_name) VALUES (?)";
my $usersQuery = "INSERT INTO users (username, account_password) VALUES (?,?)";
my $sth = $dbh->prepare($personsQuery);
$sth->execute($fName, $lName);
$sth = $dbh->prepare($compQuery);
$sth->execute($compName);
$sth = $dbh->prepare($usersQuery);
$sth->execute($email, $encpswrd);
$dbh -> disconnect;
# additional processing as needed ...
print end_html;
I get this error:
DBD::mysql::st execute failed: Field 'user_id' doesn't have a default value at /usr/lib/cgi-bin/compSignUpDBCGI.pl line 44.
I'm assuming it's likely something wrong with the handler. What am I missing??
If your persons table has a foreign key to the users table then you need insert the users record first, then get the id of the new users record and add that to the SQL to insert the persons record.
Something like this:
my $usersQuery = "INSERT INTO users (username, account_password) VALUES (?,?)";
$sth = $dbh->prepare($usersQuery);
$sth->execute($email, $encpswrd);
$sth = $dbh->prepare('SELECT user_id FROM users WHERE username = ?');
$sth->execute($email);
my $user_id = $sth->fetch->[0];
my $personsQuery = "INSERT INTO persons (user_id ,first_name, last_name) VALUES (?,?,?)";
$sth = $dbh->prepare($personsQuery);
$sth->execute($user_id, $fName, $lName);
This is an area where DBIx::Class will definitely make your life easier.

Import CSV to localhost error on import

I am having some issues with an error message that keeps coming up and I cannot locate why.
I am trying to build a process that utilises the database functionalities of WAMP on my PC to store and manipulate data rather than use MS Access.
The script below contains the current powershell script that I have been working on which is creating a new database and table to contain my CSV data however when I am trying to insert the CSV data into the newly created table it is presenting me with two repetitive errors.
The property 'CommandText' cannot be found on this object. Verify that the property exists and can be set.
And
Cannot convert value ",'" to type "System.Int32". Error: "Input string was not in a correct format."
I am simply at a loss to how to correct this and why it is throwing errors, is this obvious to anyone?
$CL2Location = 'L:\Controls\BROKER CASH RECONCILIATIONS\cl2cashpositions-331-Corrected.csv'
$dbnameone = "brokerreconciliation"
[system.reflection.assembly]::LoadWithPartialName("MySql.Data")
$mysqlConn = New-Object -TypeName MySql.Data.MySqlClient.MySqlConnection
$mysqlConn.ConnectionString = "SERVER=localhost;DATABASE=brokerreconciliation;UID=root;PWD=''"
$mysqlConn.Open()
$ccmd = New-Object MySql.Data.MySqlClient.MySqlCommand
$ccmd.Connection = $mysqlConn
$ccmd.CommandText = "DROP DATABASE IF EXISTS " + $dbnameone
$ccmd.ExecuteNonQuery()
$ccmd.CommandText = 'CREATE SCHEMA `' + $dbnameone + '`'
$ccmd.ExecuteNonQuery()
$dbonetablescript = #"
CREATE TABLE brokerreconciliation.CL2 (
`ID` MEDIUMINT(8) unsigned NOT NULL auto_increment,
`CL2ACCOUNTCODE` varchar(255) default NULL,
`ACBALANCE` varchar(255) default NULL,
`PARNAME1` varchar(255) default NULL,
PRIMARY KEY (`ID`)
) AUTO_INCREMENT=1;
"#
$ccmd.CommandText = $dbonetablescript
$ccmd.ExecuteNonQuery()
$ccmd = New-Object MySql.Data.MySqlClient.MySqlCommand
$ccmd.Connection = $mysqlConn
$ccmd.CommandText = "truncate table " + $dbnameone + ".CL2;"
$ccmd.ExecuteNonQuery()
foreach ($i in Import-Csv $cl2location) {
$cmd.CommandText =
"INSERT INTO customers (id,cl2accountcode,acbalance,parname1) VALUES ("
+$i.id+",'"+$i.cl2accountcode+"','"+$i.acbalance+"','"+$i.parname+"');"
$cmd.ExecuteNonQuery()
}
Import-Csv $CL2Location ##Added to ensure that the data file was being reached it is
$mysqlConn.Close()
Link to example CSV data is here.
Trying to resolve this problem I have tried to write the data directly from the data table created via the initial sql query to reduce the amount of steps that I would require. The code below is the update, even utilising the result set directly I am still hitting the same errors when I try to upload the data to local host.
I have also edited the CREATE TABLE element to match the schema of the base database exactly to ensure there was nothing with this that was causing the issue.
I am still at a loss as to how I cannot pass the information from either CSV or script to a newly created table on localhost.
[System.Reflection.Assembly]::LoadWithPartialName("Sql.Data")
$null = [Reflection.Assembly]::LoadWithPartialName("WindowsBase")
#####################
## - CREDENTIALS - ##
#####################
$MISA = 'xx.xx.x.xx'
$userName = 'IR'
$PassWord = 'IR'
$DB = 'IR'
$timeout = 0
###### - StopWatch - ######
$timeout2 = new-timespan -Minutes 5
$sw = [diagnostics.stopwatch]::StartNew()
##### sql ####
### MIS CL2 ###
$CL2CashPositionsScript = #'
SELECT CL2ACCOUNTCODE, sum(CAST(CL2ACCOUNTBALANCE AS MONEY)) AS CBALANCE, PARNAME1
FROM T5CASHL2 CL2 LEFT OUTER JOIN T5PARTICIPANT PAR
ON PAR.PARPDRPARTICIPANTID = CL2.CL2ACCOUNTCODE
WHERE CL2CLIENTNUM not like '315'
--AND CL2ACCOUNTCODE = '331'
GROUP BY CL2ACCOUNTCODE, PARNAME1, PARNAME2
ORDER BY CL2ACCOUNTCODE ASC
'#
## CREATE MIS CREDENTIALS ##
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection("Connection Timeout=0")
$SqlConnection.ConnectionString = "Data Source=$MISA;Initial Catalog=$DB;
Initial Catalog=$DB;User ID=$userName;Password=$PassWord;"
## - Runs Script from Set Location
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand;
$SqlCmd.CommandTimeout=$timeout;
$SqlCMD.CommandText = $CL2CashPositionsScript;
$SqlCmd.Connection = $SqlConnection;
## - Extract Data and build sql data object
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter;
$SqlAdapter.SelectCommand = $SqlCmd;
$DataSet = New-Object System.Data.DataSet;
$SqlAdapter.Fill($DataSet);
$DataSetTable = $DataSet.Tables["Table"];
#######
$CL2Location = 'L:\Controls\BROKER CASH RECONCILIATIONS\cl2cashpositions-331-Correctedb.csv'
$dbnameone = "brokerreconciliation"
[System.Reflection.Assembly]::LoadWithPartialName("MySql.Data")
$mysqlConn = New-Object -TypeName MySql.Data.MySqlClient.MySqlConnection
$mysqlConn.ConnectionString = "SERVER=localhost;DATABASE=brokerreconciliation;UID=root;PWD=''"
$mysqlConn.Open()
$ccmd = New-Object MySql.Data.MySqlClient.MySqlCommand
$ccmd.Connection = $mysqlConn
$ccmd.CommandText = "DROP DATABASE IF EXISTS " + $dbnameone
$ccmd.ExecuteNonQuery()
$ccmd.CommandText = 'CREATE SCHEMA `' + $dbnameone + '`'
$ccmd.ExecuteNonQuery()
$dbonetablescript = #"
CREATE TABLE brokerreconciliation.CL2 (
`ID` MEDIUMINT(8) unsigned NOT NULL auto_increment,
`CL2ACCOUNTCODE` char(12) default NULL,
`CBALANCE` char(20) default NULL,
`PARNAME1` varchar(30) default NULL,
PRIMARY KEY (`ID`)
) AUTO_INCREMENT=1;
"#
$ccmd.CommandText = $dbonetablescript
$ccmd.ExecuteNonQuery()
$ccmd = New-Object MySql.Data.MySqlClient.MySqlCommand
$ccmd.Connection = $mysqlConn
$ccmd.CommandText = "truncate table " + $dbnameone + ".CL2;"
$ccmd.ExecuteNonQuery()
foreach ($i in $DataSetTable) {
$ccmd.CommandText =
"INSERT INTO customers (cl2accountcode,cbalance,parname1) VALUES ("
+$i.cl2accountcode+"';'"+$i.cbalance+"';'"+$i.parname+"');"
$ccmd.ExecuteNonQuery()
}
$mysqlConn.Close()
You can't wrap strings like this:
$ccmd.CommandText =
"INSERT INTO customers (cl2accountcode,cbalance,parname1) VALUES ("
+$i.cl2accountcode+"';'"+$i.cbalance+"';'"+$i.parname+"');"
PowerShell will interpret
$ccmd.CommandText =
"INSERT INTO customers (cl2accountcode,cbalance,parname1) VALUES ("
and
+$i.cl2accountcode+"';'"+$i.cbalance+"';'"+$i.parname+"');"
as separate statements, because the first two lines are a complete statement in and by themselves. The third line then throws an error, because +$i.cl2accountcode (i.e. $null + [int]) becomes an integer, and [int] + [string] is only valid if the string can be cast to an integer (which is not the case for the string ';').
To make string concatenation work across lines you need to either escape the line break
$ccmd.CommandText =
"INSERT INTO customers (cl2accountcode,cbalance,parname1) VALUES (" `
+$i.cl2accountcode+"';'"+$i.cbalance+"';'"+$i.parname+"');"
or put the concatenation operator at the end of the line (so PowerShell knows there is more to come)
$ccmd.CommandText =
"INSERT INTO customers (cl2accountcode,cbalance,parname1) VALUES (" +
$i.cl2accountcode+"';'"+$i.cbalance+"';'"+$i.parname+"');"

Csv upload to mysql in perl

I am new in perl programming language. Can you please guide how to write csv upload into mysql database.
I have following table & csv file format
Create Table:
CREATE TABLE consumeruser (
ConsumerId int(10) NOT NULL AUTO_INCREMENT,
ConsumerName varchar(45) DEFAULT NULL,
ConsumerMobNo varchar(10) DEFAULT NULL,
PRIMARY KEY (ConsumerId)
) ENGINE=InnoDB AUTO_INCREMENT=4494 DEFAULT CHARSET=latin1
Csv file example:
4495,Sanchita Mehra,999999999
4496,Rupesh Shewalkar,88888888
4497,Aditya Mishra,111111111
Csv upload should be on basis of mobile number, suppose if table already contain mobile 111111111 Then that row should be skip. Means all mobile numbers should be check with existing data, if it is already in database that row should not be insert in database & rest of inserted into database.
You can check for the count of the row to see if the data is already present and then continue to next statement if its present. The implementation is for SQLite and you can change it to MySQL.
#!/usr/bin/perl
use Modern::Perl '2012';
use DBD::SQLite;
use warnings;
my $dbh = DBI->connect("dbi:SQLite:dbname=Consumer");
while(<DATA>){
chomp;
my ($id, $name, $MobNo) = split /,/;
my $query = "select count(*) from consumeruser where ConsumerMobNo = ?";
my $sth = $dbh->prepare($query);
$sth->execute($MobNo);
my $row = $sth->fetch();
next if(#$row > 0);
my $insertStatement = "insert into consumeruser values(?,'?',?)";
$sth = $dbh->prepare($insertStatement);
$sth->execute($id,$name,$MobNo);
}
__DATA__
4495,Sanchita Mehra,999999999
4496,Rupesh Shewalkar,88888888
4497,Aditya Mishra,111111111
4498,Aditya,111111111
Edit:
For fetching all the mobile numbers in the array. You can do like this.
my #MobileNumbers;
my $mobileNumberQuery = "select ConsumerMobNo from consumeruser";
my $sth = $dbh->prepare($mobileNumberQuery);
$sth->execute();
while(my $row = $sth->fetch()){
push #MobileNumbers, #$row;
}
Please refer to perldoc DBI for various ways of accessing the results.

SQL Insert/Update does fails, does not invoke errors

Afternoon everyone,
I'm currently trying to insert or update form field values via params into a mysql after some simple validation. The form submits, but does not actually execute any of the operations and does not raise a syntax or database connection error. I know my connection string works because I fetched values from it to compare to in the code prior to the nested evaluation blocks shown below. The foreach loops were inserted as an alternate means of validating that the values have indeed been altered in the table. Your help is greatly appreciated, as always:
my $dbusr = param("dbuser");
my $dbpw = param("dbpass");
my $dbmail = param("dbemail");
my $dbtel = param("dbphone");
my $postflag = param("Submit");
if ($dbusr ne "") {
$sth = $dbh->prepare("SELECT * FROM USER WHERE username LIKE ?");
$sth->execute('$dbusr');
warn( $DBI::errstr ) if ( $DBI::err );
my #results = $sth->fetchall_arrayref();
foreach(#results){
if ($dbusr eq $_){
$loopval = 1;
}
}
unless($loopval){
$sth = $dbh->prepare("INSERT INTO USER
(username, password, phone, email)
values
(?,?,?,?)");
$sth->execute($dbusr, $dbpw, $dbtel, $dbmail);
warn( $DBI::errstr ) if ( $DBI::err );
$sth = $dbh->prepare("SELECT * FROM USER WHERE username LIKE ?");
$sth->execute('$dbusr');
#results = $sth->fetchall_arrayref();
foreach(#results){
if ($dbusr eq $_){
$successflag = 1;
}
}
}
else{
$sth = $dbh->prepare("UPDATE USER
SET (password = ?, phone = ?, email = ?)
WHERE username = ?");
$sth->execute($dbpw, $dbtel, $dbmail, $dbusr);
warn( $DBI::errstr ) if ( $DBI::err );
$sth = $dbh->prepare("SELECT * FROM USER WHERE username LIKE ?");
$sth->execute('$dbusr');
#results = $sth->fetchall_arrayref();
foreach(#results){
if ($dbusr eq $_){
$successflag = 1;
}
}
}
}
Basic Perl: '-quoted strings do NOT interpolate variables:
$sth->execute('$dbusr');
^-- ^---
You're literally passing $, d, b, etc... to your query as the placeholder value.
Try
$sth->execute($dbusr); // note the lack of ' quotes
instead.
You are searching for entire rows with the SELECT * FROM USER WHERE username LIKE ? statement, and are then fetching all the rows in one go with
my #results = $sth->fetchall_arrayref();
That method "returns a reference to an array that contains one reference per row.", but you are treating the returned value as an list of usernames:
foreach(#results){
if ($dbusr eq $_){
$loopval = 1;
}
}
To make this work you should just fetch the username column, and treat the returned rows as references of references. And as you look for exact matches in the database replace LIKE with =:
$sth = $dbh->prepare("SELECT username FROM USER WHERE username = ?");
$sth->execute($dbusr); # no quoting
die( $DBI::errstr ) if ( $DBI::err ); # what else to do if the execute fails?
my $results = $sth->fetchall_arrayref(); # an arrayref is returned
foreach(#$results){ # de-reference the array
if ($dbusr eq $_->[0]){ # each row is an arrayref, look in first element
$loopval = 1;
}
}
(Of course the same applies to the second search.)

How to prevent null values to updating MySQL database

My update query is
"UPDATE registration SET `dob` = '".$theDate."' , pwd='".$_REQUEST['n_password']."', name='".$_REQUEST['n_name']."' where id='".$_SESSION['id']."' "
Problem is that it is not necessary that user update all fields so if it happens there are null values coming from form and it will replace earlier value in database.
I can update it one by one after checking if field value is not null but if there is any other way r tutorial please help me
I can update it one by one after checking if field value is not null
but if there is any other way r tutorial please help me
Don't issue an UPDATE query after you check each value, instead add that column to the query you're building, then execute just one UPDATE with only the columns that had values.
$dbh = new PDO('mysql:host=localhost;dbname=whatever', 'user', 'password');
$params = array();
$sql = "UPDATE REGISTRATION SET `dob` = ?";
$params[] = $theDate;
if (!empty($_REQUEST['n_password'])) {
$sql .= ", `pwd` = ?";
$params[] = $_REQUEST['n_password'];
}
if (!empty($_REQUEST['n_name'])) {
$sql .= ", `name` = ?";
$params[] = $_REQUEST['n_name'];
}
$sql .= " WHERE `id` = ?";
$params[] = $_SESSION['id'];
$stmt = $dbh->prepare($sql);
$stmt->execute($params);