PHP MySQL prepared-statement prepare() fails - php

the following returns false and i don't know how to find out what exactly is wrong.
$stmt = $dbo->stmt_init();
if($stmt->prepare("INSERT INTO transactions ('id', 'time') VALUES ('',?)")) // returns false
{
}
i have another statement which does an select open at that time. is it a problem to have more than one statements?

Have you verified that you are connecting to the database successfully?
/* check connection */
if ( mysqli_connect_errno() ) {
printf("Connect failed: %s\n", mysqli_connect_error());
}
As far as figuring out what's wrong with your prepared statement, you should be able to display $stmt->error, which will return a string description of the latest statement error, and $dbo->error, which will return the latest mysqli error.
printf("Error: %s.\n", $stmt->error);

You don't want single quotes around your table names. It should look like this:
$stmt = $dbo->stmt_init();
if($stmt->prepare("INSERT INTO transactions (id, time) VALUES ('', ?)")) {
}

just check whether those columns are properly entered... as i was getting same error coz i mentioned non existing column name in the query..

Related

Attempt to get a php prepare to work with two different tables

I am attempting to do my first query where I send to two different db tables. I am trying to update the 'group' in the users and user_request table. I am getting an id from an AJAX call, I am using that id to find the record I am trying to update.
In the users table the id will need to find the id field.
In the user_requests table the id will need to associate with the user_id.
This is the line I am trying to change to make this send to two different db tables..
$stmt = $con->prepare("UPDATE users,user_reuqests SET `group`=? WHERE id, user_id=?");
I'm getting an error responce saying the error is by the user_id part.
$approved_id = $_POST['id'];
$change_group = $_POST['update_group'];
$con = mysqli_connect("localhost","root","","db");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$stmt = $con->prepare("UPDATE users,user_reuqests SET `group`=? WHERE id, user_id=?");
if ( !$stmt || $con->error ) {
// Check Errors for prepare
die('User Group update prepare() failed: ' . htmlspecialchars($con->error));
}
if(!$stmt->bind_param('ii', $change_group, $approved_id)) {
// Check errors for binding parameters
die('User Group update bind_param() failed: ' . htmlspecialchars($stmt->error));
}
if(!$stmt->execute()) {
die('User Group update execute() failed: ' . htmlspecialchars($stmt->error));
}
What am I doing wrong to not get this to work and conjoin?
UPDATE: After I changed the prepare part of this, I'm now getting errors in my bind_param part of my prepared statement. How can I change this?
$stmt = $con->prepare("UPDATE users,user_requests SET users.group=?, user_requests.group=? WHERE users.id=? AND user_requests.user_id=?");
First, The WHERE clause in your query doesn't specify an id for the first constraint.
Second, group is ambiguous and will cause errors when you try to update it.
Your query should read:UPDATE users,user_reuqests SET users.group=?, user_request.group=? WHERE users.id=? AND user_request.user_id=?
Now, since we've updated the query with more place holders, we need to bind these additional placeholders to PHP variables. The new query uses both $change_group and $approved_id twice - so we need to bind each of them twice.
if(!$stmt->bind_param('iiii', $change_group, $change_group, $approved_id, $approved_id)) {
// Check errors for binding parameters
die('User Group update bind_param() failed: ' . htmlspecialchars($stmt->error));
}
When all is said and done, the final code should look like this:
$approved_id = $_POST['id'];
$change_group = $_POST['update_group'];
$con = mysqli_connect("localhost","root","","db");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$stmt = $con->prepare("UPDATE users,user_reuqests SET users.group=?, user_request.group=? WHERE users.id=? AND user_request.user_id=?");
if ( !$stmt || $con->error ) {
// Check Errors for prepare
die('User Group update prepare() failed: ' . htmlspecialchars($con->error));
}
if(!$stmt->bind_param('iiii', $change_group, $change_group, $approved_id, $approved_id)) {
// Check errors for binding parameters
die('User Group update bind_param() failed: ' . htmlspecialchars($stmt->error));
}
if(!$stmt->execute()) {
die('User Group update execute() failed: ' . htmlspecialchars($stmt->error));
}
More info on binding parameters to a mysqli_stmt here: http://php.net/manual/en/mysqli-stmt.bind-param.php
There's a problem with your syntax:
WHERE id, user_id=?
It should be something like this:
WHERE id = ? AND user_id = ?

Failed prepare in a prepared statement [duplicate]

This question already has an answer here:
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 7 years ago.
I am trying to GET a user ID from the previous page and output the information onto another page and in my prepared statement I am getting an error in the prepare part of the statement. What I don't get is I have this almost exact same code on another site I have and it works perfeclty. I am stumped I have looked over all of the names in my db and everything is correct.
This is the error I am getting:
prepare() failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group FROM users WHERE id = ?' at line 1
The line that is being mentioned is this one...
$stmt = $con->prepare("SELECT fullname, email, username, group FROM users WHERE id = ?");
This is the full prepared statement.
<?php
$con = mysqli_connect("localhost","root","","db");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$stmt = $con->prepare("SELECT fullname, email, username, group FROM users WHERE id = ?");
if ( false===$stmt ) {
// Check Errors for prepare
die('prepare() failed: ' . htmlspecialchars($con->error));
}
$stmt->bind_param("i", $_GET['id']);
if ( false===$stmt ) {
// Check errors for binding parameters
die('bind_param() failed: ' . htmlspecialchars($stmt->error));
}
$stmt->execute();
if ( false===$stmt ) {
die('execute() failed: ' . htmlspecialchars($stmt->error));
}
//Check errors for execute
//if(!$stmt->execute()){trigger_error("there was an error....".$con->error, E_USER_WARNING);}
$stmt->bind_result($fullname, $email, $username, $group);
$stmt->store_result();
if ($stmt->fetch()) { ?>
Am I missing something very obvious or what could be causing this?
Put a backtick (grave accents `) or quotation marks (or apostrophes) around group so it looks like this `group`. It's a MySQL keyword so that's what is messing up your query. It's good practice to always do that with your column names.

php prepared statement

It does not print the result. Dont know why. Everything is neatly commented
I get no error displays, no syntax blasphemes, it just does not print any result. However, I do know that the values are passed by the form to this processing php page, so the error is not in there. In the DB I have encrypted all fields except 'company'- Thus, I want to see if this will work by trying to fetch the results back.
// 1. Creating a new server connection
$db = new mysqli('localhost', 'root', '', 'developers');
if ($db->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
// 2, Creating statement object
$stmt = $db->stmt_init();
// 3, Creating a prepared statement
if($stmt->prepare("SELECT company FROM accesoweb WHERE username = AES_DECRYPT(?, 'salt')")) {
//4. Binding the variable to replace the ?
$stmt->bind_param('s', $username);
printf("Error: %d.\n", $stmt->errno);
// 5. Executing query
$stmt->execute();
// 6. Binding the result columns to variables
$stmt->bind_result($company);
// 7. Fetching the result of the query
while($stmt->fetch()) {
echo $company;
}
// 8. Closing the statement object
$stmt->close();
// 9. Closing the connection
$mysqli->close();
}
The inserting code that I just included in the MySQL was:
INSERT INTO accesoweb (company, username,email,password)
VALUES
('hola',
AES_ENCRYPT('maria','salt'),
AES_ENCRYPT('sumail','salt'),
AES_ENCRYPT('password',' salt')
);
So, that row above(actually, the "company" is what I am trying to recover through the PHP code
SELECT company FROM accesoweb WHERE username = AES_DECRYPT(?, 'salt')
Should be
SELECT company FROM accesoweb WHERE username = AES_ENCRYPT(?, 'salt')
OR
SELECT company FROM accesoweb WHERE AES_DECRYPT(username, 'salt') = ?

Execute multiple MySQL queries

I have 2 sql queries to execute, but I want it to execute all or if error in one query then dont execute any. I'm using php. I used to use try and catch in .NET but I'm new to php.
Below is the code which i was trying to do:
function Registration($UserFirstname,$UserLastname){
$sql="INSERT INTO table1 (fieldname1,fieldname2) VALUES ('$UserFirstname','$UserLastname')";
$res=mysql_query($sql) or die(mysql_error());
$sql="INSERT INTO table2 (fieldname1,fieldname2) VALUES ('$UserFirstname','$UserLastname')";
$res=mysql_query($sql) or die(mysql_error());}
The problem you're probably facing with try...catch is that PHP has two different error handling mechanisms: error reporting and exceptions. You cannot catch exceptions unless the underlying code throws them and good old mysql_query() will trigger warnings rather than throwing exceptions. There're several workarounds but, if you are interested in writing good object-oriented code, I suggest you switch to PDO.
In any case, if you want to stick to good old MySQL library, your code should basically work:
$res=mysql_query($sql) or die(mysql_error());
The explanation:
mysql_query() returns FALSE if the query fails (e.g., you get a duplicate key)
The right side of the or expression will only execute if the left side is FALSE
die() aborts the script, thus preventing the next queries to be executed
However, I presume that you don't want to abort in the middle of nowhere. If we add some missing bits (such as proper SQL generation and code indentation) we get this:
function Registration($UserFirstname,$UserLastname){
$sql = sprintf("INSERT INTO table1 (fieldname1,fieldname2) VALUES ('%s','%s')";
mysql_real_escape_string($UserFirstname),
mysql_real_escape_string($UserLastname)
);
$res = mysql_query($sql);
if( !$res ){
return FALSE;
}
$sql = sprintf("INSERT INTO table2 (fieldname1,fieldname2) VALUES ('%s','%s')";
mysql_real_escape_string($UserFirstname),
mysql_real_escape_string($UserLastname)
);
$res = mysql_query($sql);
if( !$res ){
return FALSE;
}
return TRUE;
}
About transactions
Please note that you still need to use transactions if there's a chance that the second query fails. Transactions are not particularly difficult to use, the only requirements are:
Define the involved tables as InnoDB
Run a START TRANSACTION query on top of the function
Run a COMMIT query at the end of the function
You need to be using transactions. These allow you to wrap a set of queries in a block that says "Either all these queries execute successfully or none of them do". This means that no matter what happens in the transaction block, you can be sure that the integrity of your database has been maintained.
NOTE: Transactions don't work with MyISAM tables, you have to use InnoDB tables.
mysql_query ('BEGIN TRANSACTION;', $db);
mysql_query ("INSERT INTO sometable (some, columns) VALUES ($some, $values)", $db);
if ($errMsg = mysql_error ($db))
{
mysql_query ('ROLLBACK;', $db);
die ($errMsg);
}
mysql_query ("INSERT INTO someothertable (some, other, columns) VALUES ($some, $other, $values)", $db);
if ($errMsg = mysql_error ($db))
{
mysql_query ('ROLLBACK;', $db);
die ($errMsg);
}
mysql_query ('COMMIT', $db);
You can try to use mysqli_multi_query
Or you can change your DB schema to InnoDB..
For executing two queries as one, you have to use mysql extension, my below code works well
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";
/* execute multi query */
if ($mysqli->multi_query($query)) {
do {
/* store first result set */
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_row()) {
printf("%s\n", $row[0]);
}
$result->free();
}
/* print divider */
if ($mysqli->more_results()) {
printf("-----------------\n");
}
} while ($mysqli->next_result());
}
/* close connection */
$mysqli->close();
?>

mysqli INSERT anomaly

I have the following table:
ID: bigint autoinc
NAME: varchar(255)
DESCRIPTION: text
ENTRYDATE: date
I am trying to insert a row into the table. It executes without error but nothing gets inserted in database.
try {
$query = "INSERT INTO mytable (NAME, DESCRIPTION, ENTRYDATE) VALUES(?,?,?)";
$stmt = $conn->prepare($query);
$name= 'something';
$desc = 'something';
$curdate = "CURDATE()";
$stmt->bind_param("sss", $name, $desc, $curdate);
$stmt->execute();
$stmt->close();
$conn->close();
//redirect to success page
}
catch(Exception $e) {
print $e;
}
It runs fine and redirects to success page but nothing can be found inside the table. Why isn't it working?
What about replacing DESCTIPTION with DESCRIPTION inside the $query?
Edit
Just out of curiosity, I created a table called mytable and copy-pasted your code into a PHP script.
Here everything worked fine and rows got inserted, except that the binded parameter CURDATE() did not execute properly and the ENTRYDATE cell was assigned 0000-00-00.
Are you sure you are monitoring the same database and table your script is supposedly inserting to?
What happens when going with error_reporting(E_ALL); ?
Have you verified that the script actually completes the insertion?
The following appears to be working as expected:
error_reporting(E_ALL);
try {
$query = "INSERT INTO mytable (NAME, DESCRIPTION, ENTRYDATE) VALUES (?, ?, CURDATE())";
$stmt = $conn->prepare($query);
$name= 'something';
$desc = 'something';
$stmt->bind_param("ss", $name, $desc);
$stmt->execute();
if ($conn->affected_rows < 1) {
throw new Exception('Nothing was inserted!');
}
$stmt->close();
$conn->close();
//redirect to success page
}
catch(Exception $e) {
print $e->getMessage();
}
Are you sure there is no error? There seems to be a typo in your column name for example.
Note that PDO is extremely secretive about errors by default.
See How to squeeze error message out of PDO? on how to fix this.
Try preparing this query instead:
"INSERT INTO mytable (NAME, DESCRIPTION, ENTRYDATE) VALUES(?,?,CUR_DATE())"
And check the results of $stmt->execute(). It would have given you a warning that "CUR_DATE()" (sic) is not a valid DATE.
You can check if a statement was correctly executed by checking the return value of execute() and querying the errorInfo() method:
if (!$stmt->execute()) {
throw new Exception($stmt->errorInfo(), stmt->errorCode());
}
Be aware that upon failure, execute() does not throw an exception automagically. You'll have to check for successful operation and failure for yourself.
Is it possible that autocommit is OFF?
If so then you have to commit your insert like so
/* commit transaction */
$conn->commit();
Regards

Categories