I'm creating a class and I have a function with which I want to insert some data into an table from some inputs. It works if I check the table but I keep getting the error "number of arguments in prepare doesn't match the no of arg in bind_result". Also I don't know if my method is correct ..
private function insertData($foldName,$foldClass,$foldLink) {
$sql = "INSERT INTO folders (folder_name,folder_class,folder_link) VALUES ('$foldName','$foldClass','$foldLink')";
if($stmt = $this->connect->prepare($sql)) {
$stmt->execute();
$stmt->bind_result($foldName,$foldClass,$foldLink);
$stmt->close();
$error = false;
$message['error'] = false;
$message['message'] = "Data Successfuly Inserted";
return json_encode($message);
}
else {
$error = true;
$message['error'] = true;
$message['message'] = "Data Failed To Insert";
return json_encode($message);
}
}
You don't need bind_result at all as you are inserting data and not selecting any.
But you should use the core features of your prepared statement. That is: safely passing the variables to the statement object instead of inserting their "raw" values into the SQL string:
$sql = "INSERT INTO folders (folder_name,folder_class,folder_link) VALUES (?,?,?)";
$stmt = $this->connect->prepare($sql);
$stmt->bind_param("sss", $foldName, $foldClass, $foldLink);
$stmt->execute();
(I have not tested it.)
Look at the first example on this manual page: http://php.net/manual/en/mysqli-stmt.bind-param.php
If you are emptying the table's data as a whole, use the truncate query:
TRUNCATE TABLE `table_name`
This would reset the auto_increment to 1, but if you don't want to empty the whole table you can alter it instead:
ALTER TABLE `table_name` auto_increment = 1
Related
I'm learning to create conditional event where sql checkout data where is exists before inserting data so they don't conflicted.
i've tried using mysql row check in php then check if query empty before i tried to validate the query executed properly.
also trying to close db connection when conditional satisfied but it worthless anyway.
$user = addslashes(strtolower($usr));
$mail = addslashes(strtolower($mail));
$pass = md5(addslashes($pwd));
$check = $db->query("SELECT EXISTS(SELECT *
FROM `users`
WHERE LOWER(`username`) = LOWER('$user')
OR LOWER(`email`) = LOWER('$mail'))");
if (!$check) {
$db->close();
return false;
} else {
$sql = "INSERT IGNORE INTO `users` (`username`, `password`, `email`)
VALUES ('$user', '$pass', '$mail')";
$query = $db->query($sql);
$db->close();
return true;
}
I'm expecting it execute my queries while data was empty and return false while data has been existed.
Your main issue is that $check will always be a truthy value, so long as the query never fails. If the query returns 0 rows, it is still a true object.
You should instead check if there were any values returned. You can also simplify the query quite a bit, given that MySQL is case-insensitive, and you don't need to check if the result exists. Using a prepared statement, the code would look like this
$stmt = $db->prepare("SELECT username FROM users WHERE username = ? OR email = ?");
$stmt->bind_param("ss", $usr, $mail);
$stmt->execute();
$check = $stmt->fetch();
$stmt->close();
// True if the user exists
if ($check) {
return false;
} else {
$stmt = $db->prepare(" INSERT INTO users (username, password, email) VALUES (?, ?, LOWER(?))");
$stmt->bind_param("sss", $usr, $pass, $mail);
$stmt->execute();
$stmt->close();
}
That said, you should not use md5() for passwords - use password_hash() with password_verify() instead.
you can change your code like this
$check = $db->query("SELECT EXISTS(SELECT * FROM `users`
WHERE LOWER(`username`) = LOWER('$user')
OR LOWER(`email`) = LOWER('$mail'))");
$check = $conn->query($sql);
$value = $check->fetch_row()[0];
if($value > 0 ){
echo "existed".$value; // you can change accordingly
}else{
echo "doesn't exist"; // this also
}
Because database respond the query in 1 for exist and 0 for non-exist so the num_row will be always 1 thats why we cant determine the existence with num_row so we have to fetch the value.
I have a script which is containing some queries:
$id = $_GET['id'];
$value = $_GET['val'];
// database connection here
// inserting
$stm1 = $db_conn->prepare("INSERT into table1 (col) VALUES (?)");
$stm1->execute(array($value));
// updating
$stm2 = $db_conn->prepare("UPDATE table2 SET col = "a new row inserted" WHERE id = ?");
$stm2->execute(array($id));
As you see there is two statements (insert and update). All I'm trying to do is making sure both of them work or none of them.
I mean I want to implement a dependency between those two statements. If updating fails, then inserting shouldn't work and vice versa. How can I do that?
You could use sql transactions
http://www.sqlteam.com/article/introduction-to-transactions
You can use transactions and PDO has an api for this (http://php.net/manual/en/pdo.begintransaction.php),
$id = $_GET['id'];
$value = $_GET['val'];
// database connection here
try{
$db_conn->beginTransaction();
// inserting
$stm1 = $db_conn->prepare("INSERT into table1 (col) VALUES (?)");
$stm1->execute(array($value));
// updating
$stm2 = $db_conn->prepare("UPDATE table2 SET col = "a new row inserted" WHERE id = ?");
$stm2->execute(array($id));
$db_conn->commit();
}
catch(PDOException $e){
$db_conn->rollBack();
}
As others said, you could use 'transactions'.
Or
you could mannualy check whether the data is right in the database. Just 'select' what you have inserted.
The 'execute' function return 'true' on success or 'false' on failure. You can do something like:
$isDone=$stm1->execute(array($value));
if(!$isDone){
echo 'Operation fails, I will stop.';
return false;
}
I am busy trying to execute a set of statements that involve the use of a temporary table.
My goal is to create the temporary table, insert values to it and then do a like comparison of the temporary tables contents to another table.
These statements are working perfectly in phpmyadmin when executed from RAW SQL, but I'm assuming that the table is not available when I try to insert the data.
Below is the code for my php function + mysqli execution:
function SearchArticles($Tags){
global $DBConn, $StatusCode;
$count = 0;
$tagCount = count($Tags);
$selectText = "";
$result_array = array();
$article_array = array();
foreach($Tags as $tag){
if($count == 0){
$selectText .= "('%".$tag."%')";
}else {
$selectText .= ", ('%".$tag."%')";
}
$count++;
}
$query = "CREATE TEMPORARY TABLE tags (tag VARCHAR(20));";
$stmt = $DBConn->prepare($query);
if($stmt->execute()){
$query2 = "INSERT INTO tags VALUES ?;";
$stmt = $DBConn->prepare($query2);
$stmt->bind_param("s", $selectText);
if($stmt->execute()){
$query3 = "SELECT DISTINCT art.ArticleID FROM article as art JOIN tags as t ON (art.Tags LIKE t.tag);";
$stmt = $DBConn->prepare($query3);
if($stmt->execute()){
$stmt->store_result();
$stmt->bind_result($ArticleID);
if($stmt->num_rows() > 0){
while($stmt->fetch()){
array_push($article_array, array("ArticleID"=>$ArticelID));
}
array_push($result_array, array("Response"=>$article_array));
}else{
array_push($result_array, array("Response"=>$StatusCode->Empty));
}
}else{
array_push($result_array, array("Response"=>$StatusCode->SQLError));
}
}else{
array_push($result_array, array("Response"=>$StatusCode->SQLError));
}
}else{
array_push($result_array, array("Response"=>$StatusCode->SQLError));
}
$stmt->close();
return json_encode($result_array);
}
The first statement executes perfectly, however the second statement gives me the error of:
PHP Fatal error: Call to a member function bind_param() on a non-object
If this is an error to do with the Temp table not existing, how do i preserve this table long enough to run the rest of the statements?
I have tried to use:
$stmt = $DBConn->multi_query(query);
with all the queries in one, but i need to insert data to one query and get data from the SELECT query.
Any help will be appreciated, thank you!
You have a simple syntax error use the brackets around the parameters like this
INSERT INTO tags VALUES (?)
This is not an issue with the temporary table. It should remain throughout the same connection (unless it resets with timeout, not sure about this part).
The error is that $stmt is a non-object. This means that your query was invalid (syntax error), so mysqli refused to create an instance of mysqli_stmt and returned a boolean instead.
Use var_dump($DBConn->error) to see if there are any errors.
Edit: I just noticed that your query $query2 is INSERT INTO tags VALUES ? (the ; is redundant anyway). If this becomes a string "text", this would become INSERT INTO tags VALUES "text". This is a SQL syntax error. You should wrap the ? with (), so it becomes INSERT INTO tags VALUES (?).
In conclusion, change this line:
$query2 = "INSERT INTO tags VALUES ?;";
to:
$query2 = "INSERT INTO tags VALUES (?);";
also note that you don't need the ; to terminate SQL statements passed into mysqli::prepare.
thanks for your time.
Below I have two prepared statements, query & query2;
con is the connection var
The first query is running perfectly and updating the database.
The second query is not updating anything, although it is not giving any error.
When I look at the second query that is logged after a "successful" run, the inserted variable is looking like an empty string. i.e. RESTI=''
Why is this happening? Is my code in the right order for the second query to run?
$row = 1;
$con=mysqli_connect("connect info");
if (mysqli_connect_errno())
{
//echo "Failed to connect to MySQL Error 1: " . mysqli_connect_error();
//error reporting done here
}
else
{
$con->autocommit(false);
$query = $con->prepare("UPDATE table where `INDEX`=?");
$query2 = $con->prepare("UPDATE table2 where (SELECT column from table where`RESTI`=?)");
$query->bind_param('i', $row);
$query2->bind_param('i', $row);
if($query->execute() == false)
{
//Failed!
/ERROR HANDLING
}
else
{
//SUCCESS
}
if($query2->execute() == false)
{
//Failed!
/ERROR HANDLING
}
else
{
//Success
}
$con->commit();
$query->close();
$query->close();
}
mysqli_close($con);
Here is how your update statement should be:
"UPDATE table SET column=<new value to set> WHERE INDEX=?"
"UPDATE table2 SET <col to update>= (SELECT column from table where`RESTI`=?) WHERE condition
Make sure RESTI is an unique field and the subquery would only return scalar value
All queries execute successfully, when I check table in MySQL row inserted successfully without any error, but lastInsertId() returns 0. why?
My code:
// queries executes successfully, but lastInsetId() returns 0
// the menus table has `id` column with primary auto_increment index
// why lastInsertId return 0 and doesn't return actual id?
$insertMenuQuery = "
SELECT #rght:=`rght`+2,#lft:=`rght`+1 FROM `menus` ORDER BY `rght` DESC limit 1;
INSERT INTO `menus`(`parent_id`, `title`, `options`, `lang`, `lft`, `rght`)
values
(:parent_id, :title, :options, :lang, #lft, #rght);";
try {
// menu sql query
$dbSmt = $db->prepare($insertMenuQuery);
// execute sql query
$dbSmt->execute($arrayOfParameterOfMenu);
// menu id
$menuId = $db->lastInsertId();
// return
return $menuId;
} catch (Exception $e) {
throw new ForbiddenException('Database error.' . $e->getMessage());
}
With PDO_MySQL we must use
$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES,TRUE); // there are other ways to set attributes. this is one
so that we can run multiple queries like:
$foo = $DB->prepare("SELECT * FROM var_lst;INSERT INTO var_lst (value) VALUES ('durjdn')");
but sadly, doing so relieves the $DB from returning the correct insert id. You would have to run them separately to be able to retrieve the insert id. This returns the correct insert id:
$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES,TRUE);
$foo = $DB->prepare("INSERT INTO var_lst (value) VALUES ('durjdn')");
$foo->execute();
echo $DB->lastInsertId();
but this won't:
$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES,TRUE);
$foo = $DB->prepare("SELECT * FROM var_lst;INSERT INTO var_lst (value) VALUES ('durjdn')");
$foo->execute();
echo $DB->lastInsertId();
and this won't even run the two queries:
$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES,FALSE); // When false, prepare() returns an error
$foo = $DB->prepare("SELECT * FROM var_lst;INSERT INTO var_lst (value) VALUES ('durjdn')");
$foo->execute();
echo $DB->lastInsertId();
Place $dbh->lastInsertId(); Before $dbh->commit() and After $stmt->execute();