mysqli_multi_query not doing anything - php

I am doing an ajax call to a PHP which should do 2 SQL queries. The queries look like this:
$sql = "UPDATE customers SET customers_newsletter=1 WHERE customers_id ='".$cid."'";
$sql .= "INSERT INTO coupons (coupon_id,
coupon_type,
coupon_code,
coupon_amount,
coupon_minimum_order,
coupon_start_date,
coupon_expire_date,
uses_per_coupon,
uses_per_user,
coupon_active)
VALUES ('".$cid."',
'NL_".$cid_substr."".$cid."',
'F',
'5.0000',
'100.0000',
'".date("Y-m-d H:i:s")."',
'".$expiredate."',
'1',
'1',
'Y'
)";
mysqli_multi_query($con,$sql);
In another php file the exact same code already worked, i there copied an sql entry to another table and then deleted it from the current one.
If i do only one of the queries it works, but i need to get them to work together.
Any ideas why it is not working?
UPDATE:
I now followed the link for preventing sql injection in the comment and i got the following code now:
<?php
$mysqli = new mysqli("server", "user", "pw", "db");
// TODO - Check that connection was successful.
$unsafe_variable = $_GET['cid'];
$stmt = $mysqli->prepare("INSERT INTO coupons (coupon_id) VALUES (?)");
// TODO check that $stmt creation succeeded
// "s" means the database expects a string
$stmt->bind_param("s", $unsafe_variable);
$stmt->execute();
$stmt->close();
$mysqli->close();
mysqli_close($con);
?>
It is still not working. Where is the fault?

What you're currently running is the same as:
$sql = "UPDATE customers SET customers_newsletter=1 WHERE customers_id ='".$cid."' INSERT INTO coupons (coupon_id,
coupon_type,
coupon_code,
coupon_amount,
coupon_minimum_order,
coupon_start_date,
coupon_expire_date,
uses_per_coupon,
uses_per_user,
coupon_active)
VALUES ('".$cid."',
'NL_".$cid_substr."".$cid."',
'F',
'5.0000',
'100.0000',
'".date("Y-m-d H:i:s")."',
'".$expiredate."',
'1',
'1',
'Y'
)";
mysqli_multi_query($con,$sql);
Which, if you notice right after the first query it starts right into the INSERT. If you ran this in anything that would give you the SQL error (or echo'd the sql error here) you'd likely see that there is a syntax error because the UPDATE query is never closed. Try adding a ; to the end of the update statement, like so:
$sql = "UPDATE customers SET customers_newsletter=1 WHERE customers_id ='".$cid."';";

Related

How to run multiple SQL queries at the same time

I have two tables, one 'comment' and the other 'pendingcomment'. I want when I copy the data of the 'pendingcomment' in the 'comment' table then that data should be deleted from the 'pendingcomment' table.
This is my code.
<?php
include '../conn.php';
$id = $_GET['id'];
// sql to Insert and delete a record
$sql = "INSERT INTO comment (blogid, name, email, subject, message, date) SELECT blogid, name, email, subject, message, date FROM pendingcomment WHERE id= $id";
$sql .= "DELETE FROM pendingcomment WHERE id=$id";
if (mysqli_multi_query($conn, $sql)) {
// mysqli_close($conn);
header('Location: ../pendingcomments.php'); //redirect to the pending page
exit;
}
else {
echo "Error deleting record ";
}
?>
Result: Error deleting record
NEVER USE mysqli_multi_query()!!!
This function is extremely unsafe and causes a lot more problems than it solves. In fact, it doesn't solve any problems, it just creates more. You can't run queries at the same time from PHP! It is impossible to do so without threading or parallelization. If you need something like this then you can check out Swoole or ReactPHP but it's probably not needed in your case.
When executing queries you need to execute them one after another using prepared statements. This is how it should be done properly:
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli('localhost', 'user', 'password', 'test');
$conn->set_charset('utf8mb4'); // always set the charset
$id = $_GET['id'];
// begin atomic transaction
$stmt = $conn->begin_transaction();
// prepare statement for insert
$stmt = $conn->prepare('INSERT INTO comment (blogid, name, email, subject, message, date) SELECT blogid, name, email, subject, message, date FROM pendingcomment WHERE id= ?');
$stmt->bind_param('s', $id);
$stmt->execute();
// prepare statement for delete
$stmt = $conn->prepare('DELETE FROM pendingcomment WHERE id=?');
$stmt->bind_param('s', $id);
$stmt->execute();
// commit transaction
$conn->commit();
header('Location: ../pendingcomments.php'); //redirect to the pending page
exit;
The transaction ensures atomicity of the operations as long as your DB engine is InnoDB or a similar transaction engine. MyISAM is not. Remember to enable mysqli error reporting or it won't work.

INSERT INTO multiple tables through multiple foreign keys

I have multiple table connected together by a few different foreign keys (see attahced image).
I am trying to insert into the projects table. I've been trying to accomplish this through the following code below, but it's not working. Right now I am getting an error saying that neither client_id_fk, project_manager_id_fk have a value. That makes sense since I didn't include them in the insert, but aren't auto incrementing and I also can't just add a random int to those fields since that throws an error as well. It technically works if I set the client_id_fk and project_manager_id_fk to NULL, but then there's no data in the other tables...Please help
$sql1 = "INSERT INTO PROJECTS (Project_Name, StartDate) VALUES( '".$_POST["Project_Name"]."','".$_POST["StartDate"]."')";
$sql2 = "INSERT INTO CLIENTS(Client_Name, Client_Email, Client_Phone) VALUES ('".$_POST["Client_Name"]."','".$_POST["Client_Email"]."','".$_POST["Client_Phone"]."')";
$sql3 = "INSERT INTO PROJECT_MANAGERS(ProjectManager_Name,Project_Manager_Email, Project_Manager_Phone) VALUES ('".$_POST["ProjectManager_Name"]."','email', 'phone')";
$sql4 = "INSERT INTO TYPE_OF_WORK(TypeOfWork) VALUES ('".$_POST["TypeOfWork"]."')";
Pattern:
-- Insert data into slave tables
INSERT INTO slave_1 (columns_1) VALUES ('values_1');
INSERT INTO slave_2 (columns_2) VALUES ('values_2');
-- Insert data into main table,
-- query FK values from slaves
-- using values inserted above
-- as filtering conditions
INSERT INTO main (columns_main, fk_column_1, fk_column_2)
SELECT 'values_main', slave_1.id, slave_2.id
FROM ( SELECT id FROM slave_1 WHERE columns_1 = 'values_1' ) slave_1
JOIN ( SELECT id FROM slave_2 WHERE columns_2 = 'values_2' ) slave_2
If it is possible that some subquery in last INSERT may return more than 1 row then wrap output column in this subquery into MAX() function (you will receive id for the last row matched - i.e. just inserted).
Step back and think about the relationships you're modelling. You have told MySQL that a Project has a Client and a Project Manager; that makes sense. Then you've tried to insert a Project with only this information:
INSERT INTO PROJECTS (Project_Name, Start_Date) ...
The error you're getting is asking you "which Client is this Project for, and who is the Project Manager?" That's something only you can know.
If it's a new Client, you need to insert that before the Project; if it's a new Project Manager, you need to insert that before the Project too. Once you've inserted them, you need to get their IDs, e.g. with the LAST_INSERT_ID() function.
If it's an existing Client and/or Project Manager, you need to look up their IDs based on whatever logic makes sense in your application.
Once you have those two IDs, you can create you Project:
INSERT INTO PROJECTS (Project_Name, Start_Date, Client_Id, Project_Manager_Id) ...
This is wrong:
$sql1 = "INSERT INTO PROJECTS (Project_Name, StartDate) VALUES( '".$_POST["Project_Name"]."','".$_POST["StartDate"]."')";
$sql2 = "INSERT INTO CLIENTS(Client_Name, Client_Email, Client_Phone) VALUES ('".$_POST["Client_Name"]."','".$_POST["Client_Email"]."','".$_POST["Client_Phone"]."')";
$sql3 = "INSERT INTO PROJECT_MANAGERS(ProjectManager_Name,Project_Manager_Email, Project_Manager_Phone) VALUES ('".$_POST["ProjectManager_Name"]."','email', 'phone')";
$sql4 = "INSERT INTO TYPE_OF_WORK(TypeOfWork) VALUES ('".$_POST["TypeOfWork"]."')";
Because you are trying to INSERT into projects a client.id and a project_manager.id that does not exist in the database. So the above should actually be written like this (in case you use mysqli):
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');
/* check connection */
if (!$link) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
// First add the client in case the table is completely empty
$stmt = mysqli_prepare($link, "INSERT INTO clients(name, email, phone) VALUES (?,?,?);");
mysqli_stmt_bind_param($stmt, 'sss', $_POST["Client_Name"], $_POST["Client_Email"], $_POST["Client_Phone"]);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
/* close statement and connection */
mysqli_stmt_close($stmt);
// Then add the project_manager in case the table is completely empty
$stmt = mysqli_prepare($link, "INSERT INTO project_managers(name, email, phone) VALUES (?,?,?);");
mysqli_stmt_bind_param($stmt, 'sss', $_POST["ProjectManager_Name"], 'email', 'phone');
/* execute prepared statement */
mysqli_stmt_execute($stmt);
/* close statement and connection */
mysqli_stmt_close($stmt);
// Also add the type_of_work in case the table is completely empty
$stmt = mysqli_prepare($link, "INSERT INTO type_of_work(TypeOfWork) VALUES (?);");
mysqli_stmt_bind_param($stmt, 's', $_POST["TypeOfWork"]);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
/* close statement and connection */
mysqli_stmt_close($stmt);
// Finally add your project
$stmt = mysqli_prepare($link, "INSERT INTO projects (project_name, start_date, client_id, project_manager_id) SELECT ?,?,client.id,project_managers.id FROM client,project_managers WHERE client.name = ? AND client.email = ? AND client.phone = ? AND project_managers.name = ?;");
mysqli_stmt_bind_param($stmt, 'ssssss', $_POST["Project_Name"],$_POST["StartDate"],$_POST["Client_Name"], $_POST["Client_Email"], $_POST["Client_Phone"],$_POST["ProjectManager_Name"]);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
/* close statement and connection */
mysqli_stmt_close($stmt);
/* close connection */
mysqli_close($link);

Insert INTO not working

I have a problem with SQL syntax. I have 2 tables and the third table is generated in SQL Workbench (n:m relationship).
My 3rd table has 2 columns product_id and categories_id.
I use this SQL in php my admin to add a new row:
INSERT INTO `products_has_categories` (`products_id`, `categories_id`)
VALUES ('17', '1');
if phpmyadmin, the sql add a new row, with product_id = 17 and categories_id =1.
My problem:
i have a simple php file called test.php looking like:
$connection = mysqli_connect("andrei.local","andrei94ro","masina", "intership");
if(!$connection)
{
echo 'error';
}
$query = "INSERT INTO `products_has_categories` (`products_id`, `categories_id`) VALUES ('17', '1');";
or
$query = "INSERT INTO `products_has_categories` (`products_id`, `categories_id`) VALUES ('17', '1')";
When i run test.php file, the code not working, and no adding new row in SQL table.
Can u help me?
As far I'm concerned, you're not even calling query().
Try this:
$connection = new mysqli("andrei.local","andrei94ro","masina", "intership");
if(!$connection)
{
echo 'error';
} else {
$query = $connection->query("INSERT INTO `products_has_categories` (`products_id`, `categories_id`) VALUES ('17', '1')");
}

SQL/PHP INSERT INTO multiple rows with $row

So pretty much my issue is that I need to send multiple SQL entries using information based on another SQL entry.
I've simplified the code down that I was using so it's easily understandable.
$sql = mysql_query("SELECT product FROM `cart` WHERE username = '".$user."' LIMIT 10");
while ($rowcart = mysql_fetch_row($sql)) {
$sendorder = "INSERT INTO Orders (order_id, product) VALUES ('NULL', '".$rowcart[0]."')";
mysql_query($sendorder);
}
When I ran it, it had failed to work; so I tried to echo $sendorder to see exactly what was sending and it turns out it's copying the INSERT INTO part on each entry, instead of just copying the values.
Example output:
INSERT INTO Orders (order_id, product) VALUES ('NULL', 'Cakes')
INSERT INTO Orders (order_id, product) VALUES ('NULL', 'Sweets')
INSERT INTO Orders (order_id, product) VALUES ('NULL', 'Cakes')
INSERT INTO Orders (order_id, product) VALUES ('NULL', 'Brownies')
INSERT INTO Orders (order_id, product) VALUES ('NULL', 'Cakes')
You said, "I need to send multiple SQL entries using information based on another SQL entry." The following approach is more efficient than what you are attempting. Note that I use neither php nor mysql so I might have some syntax errors.
insert into orders
(product)
select product
from cart
where username = $user
As far as the limit 10 goes, if you want to restrict the person to 10 items, you should do something to ensure that only 10 rows go into the cart table.
Mysqli example
<?php
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_database');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$stmt = $mysqli->prepare("SELECT product FROM `cart` WHERE username = ? LIMIT 10");
$stmt->bind_param('s', $user);
$stmt->execute();
$stmt->bind_result($product);
while($stmt->fetch()) {
$tvalue[] = $product;
}
$stmt = $mysqli->prepare("INSERT INTO Orders (product) VALUES (?)");
$stmt->bind_param("s", $one);
foreach ($tvalue as $one) {
$stmt->execute();
}
printf("%d Row inserted.\n", $stmt->affected_rows);
/* close statement and connection */
$stmt->close();
/* close connection */
$mysqli->close();
?>
If i understand correctly, what you want to do is to send an unique query, you can do this by appending every value to be inserted at the end of a single query string:
<?php
// code
$sql=mysql_query("SELECT product FROM cart WHERE username='".$user."' LIMIT 10");
$result=mysql_query($sql);
if(mysql_num_rows($result)) {
$rowcart=mysql_fetch_row("$result");
$sendorder="INSERT INTO Orders (order_id, product) VALUES ('NULL', '".$rowcart[0]."')";
while($rowcart=mysql_fetch_row($result))
$sendorder.=", ('NULL', '".$rowcart[0]."')";
mysql_query($sendorder);
}
// code
?>
I assume, your order_id is a primary key, and auto_increment. You can leave that:
INSERT INTO Orders (product) VALUES ('Cakes')
or if you really want to insert it, then use
INSERT INTO Orders (order_id, product) VALUES (NULL, 'Cakes')
if you add quotes ' around it, then it will be parsed as a string. And since, that is not a string, but integer, it will cause syntax error.
You should be able to do this in a single SQL statement something like this..
INSERT INTO Orders(order_id,product)
SELECT null,product
FROM cart
WHERE username = $name
LIMIT 0,10
To refactor even further I would suggest you probably dont need to insert the null value just do:
INSERT INTO Orders(product)
SELECT product
FROM cart
WHERE username = $name
LIMIT 0,10
If your table is structured to allow NULL in the order_id col then this will be populated as null by default.
And as Dan just said doesnt seem to be much point putting a limit on either

not updating the sql database

i wrote the following code,but its not updating the database,,its a part of a script and it cease to work..cant find a way around it .. need suggestions
<?php
$link = mysql_connect('xxxxxxxx');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("xxx", $link);
$usernames='aneeshxx';
echo $usernames;
$update = "INSERT sanjana SET $name ='$usernames'";
mysql_query($update, $link);
$update1 = "INSERT INTO sanjana (name)VALUES ($usernames)";
mysql_query($update1, $link);
?>
$update = "INSERT sanjana SET $name ='$usernames'";
this probably is meant as an UPDATE statement, so for an update it should be
$update = "UPDATE sanjana set name = '$usernames'";
I put name and not $name due to your second query and not seeing $name being defined anywhere. Be aware that this will change the value in the column name of every row in the sanjana table to the value of $usernames, normally a statement such as this gets limited by conditions, e.g. WHERE userid = 33
$update1 = "INSERT INTO sanjana (name) VALUES ($usernames)";
for an INSERT statement it needs to have the values quoted so
$update1 = "INSERT INTO sanjana (name) VALUES ('$usernames')";
Be wary that this way of putting variables directly into your query string makes you vulnerable to SQL injection, to combat this please use the PDO or mysqli extensions, they both protect you from injection by providing you with prepared statements ; plain old mysql_* is not recommended for use anymore.
using pdo you'd use prepared statements like this
<?php
// we got $usernames from wherever you define it
$pdo = new PDO('mysql:dbname=mydb;host=localhost','username','password');
// to insert
$statement = $pdo->prepare('INSERT INTO `sanjana` (name) VALUES (:name)');
// the following replaces :name with $usernames in a safe manner, defeating sql injection
$statement->bindParam(':name',$usernames);
$statement->execute(); // it is done
// to update
$statement = $pdo->prepare('UPDATE `sanjan` SET `name` = :name');
$statement->bindParam(':name',$usernames);
$statement->execute(); // it is done
so as you can see protecting your code from malicious input is not hard and it even makes your SQL statements a lot easier to read. Did you notice that you didn't even need to quote your values in the SQL statement anymore? Prepared statements take care of that for you! One less way to have an error in your code.
Please do read up on it, it will save you headaches. PDO even has the advantage that it's database independent, making it easier to use another database with existing code.
The right update sql clause is like so:
UPDATE table
SET column = expression;
OR
UPDATE table
SET column = expression
WHERE predicates;
SQL: UPDATE Statement
Your query should be like this:
$update = "UPDATE sanjana SET $name ='$usernames'";
mysql_query($update, $link);
Of course you need to specify a row to update (id), other wise, the whole table will set column $name to $usernames.
UPDATE:
Because you are inserting a data in empty table, you should first execute $update1 query then execute $update query. UPDATE clause will make no change/insert on empty table.
Problem 1: use the correct "insert into" (create new record) vs. "update" (modify existing record)
Problem 2: It's good practice to create your SQL string before you call mysql_query(), so you can print it out for debugging
Problem 3: It's also good practice to detect errors
EXAMPLE:
<?php
$link = mysql_connect('xxxxxxxx')
or die('Could not connect: ' . mysql_error());
mysql_select_db("xxx", $link);
$usernames='aneeshxx';
$sql = "INSERT INTO sanjana (name) VALUES ('" . $usernames + ")";
echo "sql: " . $sql . "...<br/>\n";
mysql_query($sql, $link)
or die(mysql_error());
You have INSERT keyword for your update SQL, this should be changed to UPDATE:
$update = "UPDATE sanjana SET $name ='$usernames'";

Categories