This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 5 years ago.
Can anybody explain why
$sql->execute($params);
returns FALSE, whereas
print $pdo->errorCode();
print_r($pdo->errorInfo());
both return SQLSTATE 00000, which means according to the documentation success? It is an INSERT and nothing is actually being inserted into the database... so, why do I get a success message from SQLSTATE?
In case it helps, this is the code...
$sql = $pdo->prepare("
INSERT INTO user (
username, fname, pass, salt, email,
loc_id_home, country_id_home, region_id_home,
cont_id_home, timestamp_reg, timestamp_upd, timestamp_lastonline,
online_status, gender, birthdate
)
VALUES (
:username,:fname,:pass,:random_salt,:email,
:loc_id_home,:country_id_home,:region_id_home,
:cont_id_home,'".time()."','".time()."','".time()."',
1,:gender,:birthdate)
");
$params=array(
':username'=>$username,
':fname'=>$fname,
':pass'=>$pass,
':random_salt'=>$random_salt,
':email'=>$email,
':loc_id_home'=>$loc_id_home,
':country_id_home'=>$country,
':region_id_home'=>$region,
':cont_id_home'=>$continent,
':gender'=>$gender,
':birthdate'=>$birthdate
);
$sql->execute($params);
print $pdo->errorCode();
print_r($pdo->errorInfo());
It is because $pdo->errorInfo() refers to the last statement that was successfully executed. Since $sql->execute() returns false, then it cannot refer to that statement (either to nothing or to the query before).
As to why $sql->execute() returns false, I don't know... either there is a problem with your $params array or with your database connection.
PDO::errorCode — Fetch the SQLSTATE associated with the last operation on the database handle
Note: The PHP manual (http://php.net/manual/en/pdo.errorinfo.php) does not define exactly what "last operation on the database handle" means, but if there was an issue with binding parameters, that error would have occurred inside PDO and without any interaction with the database. It is safe to say that if $pdo->execute() returns true, that $pdo->errorInfo() is valid. If $pdo->execute() returns false, the behavior of $pdo->errorInfo() is not explicitly clear from the documentation. If I recall correctly from my experience, execute returns true, even if MySQL returned an error, returns false if no operation was done. Since the documentation is not specific, it might be db driver specific.
This answer reflects practical experience as of when it was written in September 2012. As a user has pointed out, the documentation does not explicitly reaffirm this interpretation. It also may only reflect the particular database driver implementation, but it should always be true that if $pdo->execute() returns true, that $pdo->errorInfo() is valid.
You might also want to set PDO::ERRMODE_EXCEPTION in your connect sequence. Exception handling makes it unnecessary to check and query the error.
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
I Faced the similar problem ,
This occurs manly due to error in query, try to run your query in php-myadmin or any other query runner and confirm that your query is working fine.Even if our query syntax is correct other simple errors like leaving null or not mentioan a column that set as not null in table structure will cause this error.(This was the errror made by me)
As user1122069 explained the reason for $pdo->errorInfo() says nothing is wrong may be due to
$pdo->errorInfo() refers to the last statement that was successfully
executed. Since $sql->execute() returns false, then it cannot refer to
that statement (either to nothing or to the query before)
Hopes this helps :)
From the php manual:
PDO::ERR_NONE (string)
Corresponds to SQLSTATE '00000', meaning that the SQL statement was successfully issued with no errors or warnings. This constant is for your convenience when checking PDO::errorCode() or PDOStatement::errorCode() to determine if an error occurred. You will usually know if this is the case by examining the return code from the method that raised the error condition anyway.
So it sounds like it did insert the record. Check the last record id in your table... maybe you just missed it?
I was getting this error at one time. I only got it on one server for all failures. A different server would report the error correctly for the same errors. That led me to believe it was a MySQL client configuration error. I never solved the specific error, but check your configurations.
Try to check $sql by print_r() and copy your query then try resultant query in phpMyadmin. Hope will get the reason. There would be chance of irrelevant value.
Related
This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 6 years ago.
I am trying to bind a variable in this prepared statement, but i keep receiving the error:
Call to a member function bind_param() on a non-object
The function is called, and variables are passed to it. When i change the function to just echo the variable, the variable prints on the page fine, but if i try to bind it here i receive the error. can anyone help?
//CALL FROM PAGE ONE
check($username);
//FUNCTION ON PAGE 2
function check($username){
$DBH = getDBH();
$qSelect = $DBH->prepare("SELECT * FROM users WHERE username = ?");
$qSelect->bind_param("s", $username);
}
i know the function is not completely written here, but that shouldn't be a problem. I don't understand why i am receiving this error.
Well, one reason prepare() can fail is if the sql statement sent to it is not valid in the current DB.
prepare() will then return false.
Eg - if the table name is not correct or one or more field in the query does not exist.
as the error-message says, $qSelect seems to be not an object. try to debug this by using var_dump($qSelect); right after your prepare-call. also check if getDBH() returns what you need.
sounds like the prepare-call fails (don't know why) and so it returns false - false is not an object, so you can't call bind_param() on that.
EDIT: you havn't given the info, but it looks like you're using PHP's PDO. In that case, take a look at the documentation.
If the database server successfully
prepares the statement, PDO::prepare()
returns a PDOStatement object. If the
database server cannot successfully
prepare the statement, PDO::prepare()
returns FALSE or emits PDOException
(depending on error handling).
You should configure your server to return those PDO-Exceptions, which would tell you why the prepare call fails.
i'm using the mysqli approach as well and got the same error when I created another instance of mysqli before closing the first instance. So its important to use close() before starting the same piece of code. For example:
$DBH = getDBH();
$qSelect = $DBH->prepare("SELECT * FROM users WHERE username = ?");
$qSelect->bind_param("s", $username);
$qSelect->close(); // <--- use close before calling the same function( wich contains $DBH code) again;
It appears that prepare is quite dumb. It doesn't rely query entirely into the MySQL side, by this, I mean, if in your query, you have a table that happens to have the same name of a keyword, say "user", "order", ..., it just doesn't recognize it as a table, but rather as what the keyword commands actually do, so the query turns out to be a mess and the prepare just fail.
To fix this is simple, you have to type it in the "correct" way adding "`" in both sides of the table name. Example:
`user`, `order`, `...`
It's correct, yet, I find it silly from prepare to have this behavior.
I am trying to help other people with little experience in PHP like me.
In my case, this error occurred because I had an SQL syntax error. The console stack trace did not show the problem.
When I fixed the SQL, the error was gone.
Check the permissions of the user in database. User without "insert" permission causes "Call to a member function bind_param() on a non-object" message error too, when trying to insert.
I'm using MySQL with strict mode turned on. I am inserting data supplied by user through an HTML form. I've already done all my validation and this is the final step.
Here is an excerpt from my PHP code:
$sql = 'SET sql_mode = TRADITIONAL'; //last chance data validation
$mysqli->query($sql) or output_error('Database Error: Failed to set SQL mode');
$db_err_msg = 'Database Error: Failed to update profile summary';
$sql = "INSERT INTO {$tables['text']} (lngProfileId, memProfileText) VALUES(?, ?)
ON DUPLICATE KEY UPDATE memProfileText = VALUES(memProfileText)";
$stmt = $mysqli->prepare($sql) or output_error($db_err_msg);
$stmt->bind_param('is', $profile_id, $_POST['memProfileText'])
or output_error($db_err_msg);
$stmt->execute() or output_error($db_err_msg);
$stmt->close();
//if code reaches this point, can it assume insert/update succeeded?
Note: output_error is my error handler for fatal errors. It doesn't return; it exits.
Do I need to check for warnings? Or can I safely assume the insert/update succeeded? Is there some scenario that could cause a warning instead of an error even with strict mode turned on?
EDIT: I'm only concerned about things that should be considered fatal errors. If it was updated rather than inserted, that is of no concern to me. That's not an error.
Also, last_insert_id and affected_rows are meaningless in this case. If the user didn't make any changes, affected_rows will be 0 and the value of last_insert_id will not be updated.
My definition of succeeded in this case:
it inserted the record or updated the record or did nothing if no changes were made
it did not 'silently mangle my data'
Many newbie programmers make the mistake of assuming that a query succeeded without ever checking the return value or warnings. Their code works... under normal conditions.
My question is: "Considering my code, with strict mode turned on, and the error checking I've done, is it safe to assume the query succeeded? Is that a correct or incorrect assumption? Should I also check for warnings or would that be redundant?"
You should check the value of mysqli::info() function.
If it inserts data the string will look something like this,
Records: 1 Duplicates: 0 Warnings: 0
Another function is mysqli::affected_rows. it returns the number of rows affected for last insert/update/delete query.
Yes you can safely assume that, but just for a double check Fetch the ID of the latest record that is inserted. If there is an id, it was inserted then
While I think that it's probably a safe assumption, I figured better safe than sorry. I've added the following code directly after the execute statement before the close statement.
//I think this is probably redundant, but just in case
if ($mysqli->warning_count) {
$warnings = $stmt->get_warnings();
do {
trigger_error('Database Warning (' . $warnings->errno . '): '
. $warnings->message, E_USER_WARNING);
} while ( $warnings->next() );
}
I've added the comment so that I remember why I did that.
This question already has answers here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(2 answers)
Closed 9 months ago.
I've verified all variables below and am now attempting to insert them into my mysql database using prepared statements, but the data is not inserting even though I am not receiving any system errors. $insert_stmt->affected_rows>0 returns false, and thus displays my custom warning message:
$insert_stmt = $db->prepare("INSERT INTO users (id,timestamp,externalid,password,authentication,email) VALUES(NULL,NOW(),?,?,?,?)");
$insert_stmt->bind_param("ssss",$userid,$hash,$authenticate,$email);
$insert_stmt->execute();
if ($insert_stmt->affected_rows>0)
I'm somewhat new to PHP (and the community) and can't figure out why nothing would be inserting and my custom warning message always displays? Again, no system errors are generated. Thanks!
Chances are there is an error when execute() is called. execute() will return TRUE if the statement succeeded and FALSE on failure. So check the return value. If it's FALSE, call mysqli_stmt_error() for information about the problem.
I figured out the issue. I was testing with an externalid that was already in the database, and my check for preventing duplicate external ids was not working correctly, so my code was reaching the insertion line and trying to put the externalid again into MySQL when it already existed in the database. I had set the externalid as a unique field, so it wouldn't allow it to be entered. MySQL though didn't return any noticeable errors when I had set E_ALL | E_STRICT. Good to know in the future.
I didn't realize I was testing with a duplicate entry, so sorry to the community for adding that nugget of info.
Please do the following:
1) Look at this link:
PHP PDO code to insert in MySQL db fails
2) Add this after you connect to the database:
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
3) Add this try/catch block around your prepare, bind and execute statements:
try { .. } and catch (Exception $e) { echo $e->getMessage(); }
4) Report back what - if any - error messages you get
And be sure to check the error status of your calls. Particularly $insert_stmt->execute().
This question already has answers here:
PDO SQL-state "00000" but still error? [duplicate]
(5 answers)
Closed 5 years ago.
I have the code below:
$sql3 = "update news set date='$time' where id='2'";
$sql3 = $connect->exec($sql3);
if(!$sql3)
{
print_r($connect->errorInfo());
$error = $connect->errorInfo();
die ("Error: (".$error[0].':'.$error[1].') '.$error[2]);
}
When I run the script, sometimes I get error number '00000'. I mean it goes intro the IF. and it is all random. output (sometimes):
Array ( [0] => 00000 [1] => [2] => )
What should I do to fix this problem ?
PS: The script executes correctly every time.
The PDO error code 00000 means that everything works fine. The reason you're hitting the error-checking code is that $sql3 is returning 0 (no rows were effected) and PHP evaluates that to false. Try explicitly checking for a return false;
if($sql3 === false)
If exec does not update any row, it will return 0. that makes if(!$sql3) evaluate to false, you should do this instead :
if($sql3 === false){
}
In my experience badly formed queries (syntax errors) and failed queries (for example an INSERT that didn't insert anything) also may WRONGLY return error code 00000. You should go ahead and try to run the complete query on your SQL console and see why it failed. I really don't know why the proper error message isn't returned though. Here's a snippet of the code we use
$r = $pdo->prepare($sql);
if (!$r->execute($input_parameters)) { # query failed
if ($bLogFailures) {
error_log('query failed: ERROR['.$pdo->errorCode().':'.print_r($pdo->errorInfo(), true).'] QUERY['.$sql.']');
}
return false;
}
I just got similar situation in my php project - it occured that PDO Exception with error code '00000' took place when I tried to insert row with a field set to NULL while column defining the field in the database was of type ENUM('0', '1') and restriction NOT NULL.
After modifying PHP script to place '0' instead of NULL, the error perished.
Further coding brought more light into the situation - I was performing more than one PDO statments within one DB transaction but checking errors (in Exception handling block) basing only on the first PDO statement executed while real error occured int the third PDO statement.
00000 means, it works fine. you should change your if to this: $sql3 === false.
I had the same problem. It also tortured me a lot, but finally figured it out.
Suppose you have 7 columns in your table.
You are inserting data into 4 of them.
If for remaining 3 columns the default value is not set (say NULL for alpha-numeric columns, CURRENT_TIMESTAMP for date-time related columns etc.) then the above stated problem occurs.
If you are inserting data into all of those 7 columns or at least in those columns for which default value is not set, you wont get any error and data will get inserted.
The PDO::exec statement returns an integer to indicate the number of rows that were affected. So in your particular case, as the SomeKittens indicates, if 0 rows were affected, then your error code would be triggered.
However, if you are concerned as to whether your query worked, your better action may be to use PDO::query (in terms of your code ($returnObj = $connect->query($sql3) instead of PDO::exec.
The $returnObj can then be checked to see if there was an error in the SQL execution, and you can then troubleshoot your SQL query because it will tell you what the error was and where it was located.
Your best bet to do this would be:
//set PDO to throw an error so you can wrap the query in a try / catch block.
$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql3 = "update news set date='$time' where id='2'";
try {
$returnObj = $connect->query($sql3);
} catch (PDOException $e) {
print_r($returnOjb->errorInfo());
$error = $returnObj->errorInfo();
die ("Error: (".$error[0].':'.$error[1].') '.$error[2]);
}
PLEASE READ THE QUESTION CAREFULLY. It is not usual silly "my code doesn't work!!!" question.
When I run this code with intended error
try {
$sth = $dbh->prepare("SELECT id FROM users WHERE name INN(?,?) ");
$sth->execute(array("I'm","d'Artagnan"));
} catch (PDOException $e) {
echo $e->getMessage();
}
I get this error message
You have an error in your SQL syntax ... near 'INN('I\'m','d\'Artagnan')' at line 1
But I thought for years that query and data being sent to the server separately and never interfere. Thus I have some questions (though I doubt anyone got an answer...)
Where does it get such a familiar string representation - quoted and escaped? Is it being made especially to report an error or is it a part of actual query?
How does it work in real? Does it substitute a placeholder with data or not?
Is there a way to get whole query, not only little bit of it, for debugging purposes?
Update
mysqli does it as expected: it throws an error says near 'INN(?,?)'
try adding
$dbh->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
;)
I'm not sure about all the details, but I will try to answer.
The quotation happens on the database side. The database escapes and sanitizes all values (see bullet 2) it receives so that it gets interpreted correctly.
The moment the error is thrown, the database (in this case MySQL) prints out the query it tried to run. This wouldn't be so helpful if it just showed the prepared part.
No, it doesn't. At preparation time the query gets compiled on the server side. When a query is executed with values, only the values are transmitted. This is pretty much the same as calling PREPARE and EXECUTE on the database directly.
This depends on the database you're using. MySQL for example can log all queries to a log file (check my.cnf settings for that). But you can also use debugDumpParams() on PHP side.
I hope this was a bit helpful.