I am attempting to prepare a statement with mysqli
$stmt = $mysqli->prepare("INSERT HIGH_PRIORITY INTO `user` (`FirstName`, `LastName`, `Department`, `Email`) SELECT * FROM (SELECT ?,?,?,?) AS tmp WHERE NOT EXISTS ( SELECT `Email` FROM `user` WHERE `Email` = ? ) LIMIT 1;");
if (!$stmt) {
printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
die;
}
$statementReturnCode = $stmt->bind_param("sssss", $ssoFirstName, $ssoLastName, $ssoDepartment, $ssoEmail, $ssoEmail);
if (!$statementReturnCode) {
printf('errno: %d, error: %s', $stmt->errno, $stmt->error);
}
$stmt->execute();
$stmt->close();
When this is run I receive the following error:
errno: 1060, error: Duplicate column name '?'
I've been able to bind in this fashion in the past, but I've never tried to bind the same column twice in a different location in the query (Email).
How can I use the same value for Email in two different locations, or is this a different issue?
To clarify what is being done with this query:
This query will be run frequently. If the user exists already in the user table, no insert should be attempted. If the user does not exist, the user should be added to the user table.
The user table has a UserID field that auto-increments. If an insert is attempted the user will not be added due to a unique constraint, but the AUTO-INCREMENT will add 1 even though the insert did not occur. This WHERE NOT EXISTS query is an attempt to mitigate this issue.
Example use:
INSERT INTO `user` (
`user`.`FirstName`,
`user`.`LastName`,
`user`.`Department`,
`user`.`Email`)
SELECT * FROM (SELECT 'John', 'Doe', 'Marketing', 'John.Doe#mycorp.com') AS tmp
WHERE NOT EXISTS (
SELECT `user`.`Email`
FROM `user`
WHERE `user`.`Email` = 'John.Doe#mycorp.com'
) LIMIT 1;
I have tested this query and it works as I had expected. The issue I'm having is with properly changing this query into a prepared statement with php.
Column names aren't string literals, you don't bind column names
$stmt = $mysqli->prepare(sprint("INSERT HIGH_PRIORITY INTO `user` (`FirstName`, `LastName`, `Department`, `Email`) SELECT * FROM (SELECT '%s', '%s', '%s', '%s') AS tmp WHERE NOT EXISTS ( SELECT `Email` FROM `user` WHERE `Email` = ? ) LIMIT 1;"), $ssoFirstName, $ssoLastName, $ssoDepartment, $ssoEmail);
if (!$stmt) {
printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
die;
}
$statementReturnCode = $stmt->bind_param("s", $ssoEmail);
if (!$statementReturnCode) {
printf('errno: %d, error: %s', $stmt->errno, $stmt->error);
}
This cannot be done. Prepared statements using PHP's mysqli extension cannot be used for several things including:
Table names
Columns in select lists
I was attempting to use a dynamic item in a select list which cannot be done.
https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet#Where_prepared_statements_do_not_work
Related
I have connected to the db and able to update a record.
I have a variable named "action" that is either "update" or "add".
I use it in a switch statement to set my query to either "SELECT" or "INSERT".
SELECT statement works.
INSERT statement does not.
I get this error on $pdo->execute($data).
PHP Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in ...
PDOStatement->execute(Array)
The error is thrown by the PDOStatement
Here is what I have tried, seems pretty straight-forward, but i'm struggling with it.
$data = [
'firstName'=> $firstName,
'lastName'=> $lastName,
'badge'=> $badge,
'department'=> $department,
'image'=> $image,
'active'=> $active,
'stars'=> $stars,
'email'=> $email,
'primary_key'=> $primaryKey,
];
$sql = "INSERT INTO `team`
(`primary_key`,`firstName`, `lastName`, `badge`, `department`, `image`, `active`, `stars`, `email`)
VALUES
(NULL, :firstName, :lastName, :badge, :department, :image, :active, :stars, :email)";
$pdo->prepare($sql);
$pdo->execute($data); <- error is here
When I simply echo my $data array to see if there is something odd. I don't see anything based off all the sites, I've read.
//$data array DATA
primary_key =
firstName = test
lastName = test
badge = 9000
department = marketing
image = 9000.jpg
active = 1
stars = 0
email = tester#test.com
primary_key in db is auto-increment
primary_key is $_post[] on update query and NULL insert query (auto increment db column)
Any errors that would prevent this INSERT query from working that you can see? I'm stuck. I know it the array has 9 variables, there are 9 fields to insert, and 9 values listed.
I know it the array has 9 variables, there are 9 fields to insert, and 9 values listed.
Count the parameters. There are 8 of them. The array includes a value called primary_key for which there is no parameter in the query.
primary_key in db is auto-increment
Then don't insert a value for it:
$sql = "INSERT INTO `team`
(`firstName`, `lastName`, `badge`, `department`, `image`, `active`, `stars`, `email`)
VALUES
(:firstName, :lastName, :badge, :department, :image, :active, :stars, :email)";
And remove primary_key from the $data array.
My project is a simple attendance record for my small school. I am submitting entry and exit logs through an online form, and writing them to a database with this query:
$sql = "INSERT INTO table_one (first_name, last_name, location)
VALUES ('$first_name', '$last_name', '$location')";
It works fine - so far so good.
At the same moment I would like to write some of this submitted information to another table in the same database. This query works fine by itself when standing alone:
$sql = "UPDATE another_table SET location='$location' WHERE first_name='$first_name'";
However my problem is how to make them both happen, in sequence. Just listing them successively doesn't work:
$sql = "INSERT INTO table_one (first_name, last_name, location) VALUES
('$first_name', '$last_name', '$location')";
$sql = "UPDATE personnel_table SET location='$location' WHERE
first_name='$first_name'";
What is the most effective (and safest) way to combine both commands so that they execute together?
You need to use transaction so that if one query fail, both should fail. Only if both query success that it will add/update the database.
$db= new PDO('mysql:host=localhost; dbname=test', $user, $pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$db->beginTransaction();
$sh = $db->prepare("INSERT INTO table_one (first_name, last_name, location) VALUES (?, ?, ?)");
$sh->execute([$first_name, $last_name, $location]);
$sh = $db->prepare("UPDATE personnel_table SET location=? WHERE first_name=?");
$sh->execute([$location, $first_name]);
$db->commit();
} catch ( Exception $e ) {
$db->rollBack();
}
for this problem you must use trigger option in database (forEx mysql).
trigger is like an event. when insert in on table automate update second table. forEx:
mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account
FOR EACH ROW SET #sum = #sum + NEW.amount;
Query OK, 0 rows affected (0.01 sec)
this trigger that is a object for account table. update #sum variable and then use for update second table
You can create a trigger like below:
delimiter #
create trigger after_ins_trig after insert on first_table
for each row begin
UPDATE second_table
SET new.location=old.location
WHERE new.first_name=old.first_name end#
delimiter ;
You can check id in where clause.
Why not this:
Table: teraz
Create Table: CREATE TABLE `teraz` (
`col` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
//
<?php
$last_name = 77;
$conn = new mysqli('localhost','root','','shopping');
$sql = "INSERT INTO teraz VALUES ('{$last_name}')";
$sql2 = "SELECT * FROM teraz";
$conn->query($sql);
$result = $conn->query($sql2);
$x = $result->fetch_assoc() ;
echo $x['col'];
?>
?
I need to update and insert around 1 Million data in mysql data base, when I am using the following code It takes more time. please suggest how can i update and insert the data fastly?
include('db.php');
include('functions.php');
$functions=new functions();
set_time_limit(0);
$column="rank"."_".date("Y-m-d");
$count=$functions->get_row("SELECT COUNT(id) as ct FROM alexa_filename WHERE status=1");
if($count->ct==100){
$alexas=$functions->get_result("SELECT DISTINCT (`sitename`),`$column` FROM `top-2m` WHERE `status`=0 LIMIT 100" );
if(!empty($alexas)){
foreach($alexas as $alexa){
$site_name=$alexa->sitename;
echo $site_name;
$rank=$alexa->$column;
$table=$functions->find_table_name($site_name);
$count=$functions->get_row("SELECT COUNT(site_name) as ct FROM `$table` WHERE site_name='$site_name'");
if($count->ct==0){
$functions->set_query("INSERT INTO `$table`( `site_name`, `other_id`, `response`, `category`, `updated`, `site_update`, `wot_update`, `social_update`, `google_update`, `server_update`, `alexa_update`, `backlinks_update`, `antivirus_update`, `key`, `desc`, `google_backlink`, `images_url`, `images`, `tag`, `view_count`, `title`, `api_update_time`, `table_name`, `user_added_similar`, `auto_similar`, `comments`, `status`) VALUES ('$site_name',0,0,0,0,0,0,0,0,0,$rank,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)");
$functions->set_query("UPDATE `top-2m` SET `status`=1 WHERE sitename ='$site_name'");
}else{
$functions->set_query("UPDATE `$table` SET `alexa_update`=$rank WHERE site_name='$site_name'");
$functions->set_query("UPDATE `top-2m` SET `status`=2 WHERE sitename ='$site_name'");
}
}
}else{
mail("aaa#aaa.com","Alexa_Cron_Update_Status","aaaRank Is Succes fully Updated");
}
}
You can insert/update multiple rows using INSERT ... ON DUPLICATE KEY
UPDATE.
Reindex your database.
Use Prepared Mysql Statements.
Also If you are using Linux/ubuntu try to use terminal instead of browser. It will make a lot difference.
Concatenate your INSERT and UPDATE Query to $qry and apply
$functions->set_query($qry);
once your looping done. This will take less time.
Edited:
Example:
$qry = "Insert into table values('', '', '','', '')";
$qry .= "insert into table2 values('', '', '','', '')";
$qry .= "insert into table3 values('', '', '','', '')";
$qry .= "update table3 set field = 'something' ";
and out of condition or loop.
$functions->set_query($qry);
I use this solution (the accepted one) to insert no duplicates, because I can't set an unique index (table belong to another software), this way:
$InsertAddress = $DatabaseConnection -> prepare("INSERT INTO `tt_address` (`pid`, `tstamp`, `first_name`, `last_name`, `email`, `phone`, `address`, `city`, `zip`) SELECT * FROM (SELECT 272 AS `tmp_pid`, ? AS `tmp_tstamp`, ? AS `tmp_first_name`, ? AS `tmp_last_name`, ? AS `tmp_email`, ? AS `tmp_phone`, ? AS `tmp_address`, ? AS `tmp_city`, ? AS `tmp_zip`) AS `tmp` WHERE NOT EXISTS (SELECT `email` FROM `tt_address` WHERE `email` = ?) LIMIT 1")
$InsertAddress -> bind_param('issssssss', $Timestamp, $_POST['firstname'], $_POST['lastname'], $_POST['mail'], $_POST['phone'], $_POST['address'], $_POST['ort'], $_POST['plz'], $_POST['mail']);
$InsertAddress -> execute();
echo($DatabaseConnection -> error);
But I get the following error:
Column count doesn't match value count at row 1
If I copy the query in phpMyAdmin and replace the ? with sample data the query works.
What is wrong?
Parameter markers (the question marks) can't be used for column names.
Here's my code:
$con=mysqli_connect("localhost","name","pass","bird") ;
$result = mysqli_query($con,"SELECT * FROM bird");
mysqli_query($con,"INSERT INTO 'bird' (`id`, `name`, `latin`, `number`) values (0,'d','cwer','73')");
the first time, I could see the the values were added but when I reloaded, it didn't do any more, is it supposed to be like this ?
So if I want it to run every time I reload, how can I do that?
You probably have a unique constraint against your id column (or another column in that query) and when you try to add a second row using the same ID it is rejected by MySQL.
You should be doing error checking in your code. You should be checking to see how many rows were affected by your insert (using mysqli_affected_rows()) and, if the number is zero, getting the error message from MySQL (using mysqli_error()).
$result = mysqli_query($con,"INSERT INTO 'bird' (`id`, `name`, `latin`, `number`) values (0,'d','cwer','73')");
if (mysqli_affected_rows() === 0) {
echo mysqli_error($con);
}
#DaveChen's comment above is a good solution to your (potential) problem. If it isn't already, make your id column auto increment and then leave it out of your query.
mysqli_query($con,"INSERT INTO 'bird' (`name`, `latin`, `number`) values ('d','cwer','73')");
If your id column is aut_increment and unique: change your code to:
$con=mysqli_connect("localhost","name","pass","bird") ;
$result = mysqli_query($con,"SELECT * FROM bird");
mysqli_query($con,"INSERT INTO 'bird' (`id`, `name`, `latin`, `number`) values ('','d','cwer','73')");