I'm trying to insert into my database and have been frustratingly not been able to get my statement(s) to work. I'm using PHP's MySQL Improved (mysqli) procedural interface. It might be worth noting that I'm using the c9.io IDE (pre-AWS) and everything including the server that my application is running on is through c9.
What I've noticed is that the statements have been working randomly. Initially, I was making very subtle changes to my INSERT statements until it worked, but after the working trial, it would fail again. So, eventually I started hitting the refresh button (same inputs, no modifications to my code) repeatedly until I hit a success.
In terms of code:
$sql = "INSERT INTO `users` (`email`,`password`) VALUES ('example#mail.com','1234')";
$result = mysqli_query($connection,$sql);
gives
$result = false
very consistently, but every random nth trial
$result = true
(same inputs, no change to my code).
I do not believe it is an error with my SQL syntax considering the random successes, nor do I believe it is an error with my connection. All of my SELECT statements have been working fine.
Thus, I have a hunch that for some reason it may be an issue with c9? If you have ever had a similar issue with any of MySQL, SQL, PHP, or c9, please help!
You Should try this
<?php
if (!mysqli_query($connection,"INSERT INTO Persons (FirstName) VALUES ('Glenn')"))
{
echo("Error description: " . mysqli_error($connection));
}
?>
Use myqli_error() which will give you a error message which should help clarify the issue with your code
Related
I am maintaining a server that runs for around 1 year. Nothings gonna be wrong previously. However, suddenly, there is an error in mysql_insert_id(), which returns 0, instead of normal row id from the database. Here's are the core of the code.
$sql = "INSERT INTO $db_table (name,email) VALUES('$name','$email')";
mysql_query($sql);
$current = mysql_insert_id();
Also notice that even if there are no changes in the code, the program runs smoothly again after the error has happened. It seems strange to me.
Here is my possible explanation. Since I am hosting in a public server, where many are using the same MYSQL server. Will it be that when mysql_query($sql), the server then swap the process and let another guy to run another SQL command, which may be for example, a SELECT statement, and after their execution, it swaps back to my own code and continue executing, which results in 0?
Please help. Thanks.
to be sure use the resource_identifier as parameter in mysql_queryand mysql_insert_id.
If you don't, the last connection to the mysql server is used, as you thought.
$resource = mysql_connect(...);
$sql = "INSERT INTO $db_table (name,email) VALUES('$name','$email')";
mysql_query($sql, $resource);
$current = mysql_insert_id($resource);
Please consider using mysqli oder PDO since mysql_* functions are deprecated and are going to be removed in future PHP-Versions
the issue
So I bumped into something curious this morning when I was updating my database. I executed a collation change in my database, changing it from latin1 to uft8. However, my queries failed suddenly on my table. After some debugging, (rebuilding the table even with its original setup, but to no such avail) and receiving 500 internal errors, i realized it had to do with the prepared statement, so i tore it out, and replaced it with a regular mysqli_query, and it surprisingly worked. So now I am wondering, was my prepared statement wrong the whole time, or did it fail because of a change in the database.
the setup
This is the current table set up. I changed it back to latin (and its innoDB) yet it didnt gave me the results back i wanted when i changed everything back to the original settings (which is how it is now)
the code
the original code was this and it worked fine until the change
require_once '../db/dbControl.php';
$id = mysqli_real_escape_string($con,$_GET["id"]);
$sql = "SELECT *
FROM project
WHERE project.ProjectId = ? ";
$stmt1 = mysqli_prepare($con, $sql);
mysqli_stmt_bind_param($stmt1,'i',$id);
mysqli_stmt_execute($stmt1);
mysqli_stmt_bind_result($stmt1,$ProjectId,$ProjectTitel,$ProjectOmschrijving, $ProjectOmschrijving,$ProjectDatum,$ProjectClient,$ProjectUrl);
while (mysqli_stmt_fetch($stmt1)){
the code itself of the page
}
So right now I am just using a regular mysqli_query in order to make it work
require_once '../db/dbControl.php';
id = mysqli_real_escape_string($con,$_GET["id"]);
$sql = "SELECT *
FROM project
WHERE project.ProjectId = '". $id ."'";
$result = mysqli_query($con,$sql);
while($rows=mysqli_fetch_array($result)){
$ProjectId = $rows['ProjectId'];
$ProjectTitel = $rows['ProjectTitel'];
$ProjectExpertise = $rows['ProjectExpertise'];
$ProjectOmschrijving = $rows['ProjectOmschrijving'];
$ProjectDatum = $rows['ProjectDatum'];
$ProjectClient = $rows['ProjectClient'];
$ProjectUrl = $rows['ProjectUrl'];
the code itself of the page
}
I am a little bit confused (maybe i overlooked something here because to focussed on a little bit of code) but it only happens on the project table. I checked it against code that involves readouts, and they work all fine with prepped statements.
Hope anyone can spot what I couldn't
I wont be able to tell you what happened but here are two thought's.
The prepared statement execution consists of two stages: prepare and
execute. At the prepare stage a statement template is sent to the
database server. The server performs a syntax check and initializes
server internal resources for later use.
A prepared statement can be executed repeatedly. Upon every execution
the current value of the bound variable is evaluated and sent to the
server. The statement is not parsed again. The statement template is
not transferred to the server again.
Maybe this is what happened, it could be that the prepared statements never reseted after you changed to utf8.
Every prepared statement occupies server resources. Statements should be closed explicitly immediately after use. If not done explicitly, the statement will be closed when the statement handle is freed by PHP.
Using a prepared statement is not always the most efficient way of
executing a statement. A prepared statement executed only once causes
more client-server round-trips than a non-prepared statement. This is
why the SELECT is not run as a prepared statement above.
Maybe the server memory (is/was) full?
Tekst from:
http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
I'm trying to loop data from a api and then post these values to a MySQL db.
something like this:
$values = json_decode(file_get_contents("my-json-file"));
$SQL = new mysqli(SQL_HOST, SQL_USER, SQL_PASS, DB_NAME);
$SQL->autocommit(FALSE);
foreach($values As $item)
{
$query = "INSERT INTO my_table VALUES ('".$item->value1."', '".$item->value2.";)";
$SQL->query($query);
if(!$SQL->commit())
{
echo "ERROR ON INSERT: [" . $query . "]<hr/>";
}
}
$SQL->close();
Since the loop is too fast, the SQL can't catch up. (Yea!)
I would then need something like this:
foreach($values As $item)
{
/**** STOP/PAUSE LOOP ****/
$query = "INSERT INTO my_table VALUES ('".$item->value1."', '".$item->value2.";");
$SQL->query($query);
if($SQL->commit())
{
/**** START THE LOOP AGAIN ****/
}
else
{
echo "ERROR ON INSERT: [" . $query . "]<hr/>";
}
}
Or how should I do this the right way?
EDIT: It inserts random posts every time.
EDIT 2: This is just example code. It does escape and all that, and yes the semi colon is wrong here but since so many commented on it i will not change it. This was not the problem in the real case.
I tried to run it on another server and there it worked. The problem was fixed by restarting MAMP.
Firstly, your idea that the loop runs too fast for MySQL to keep up is completely totally wrong. The $SQL->query() call will wait for the MySQL to return a response before proceeding, so the loop won't run any faster than MySQL is responding.
Now onto the actual problem.... your query:
$query = "INSERT INTO my_table VALUES ('".$item->value1."', '".$item->value2.";)";
There's a semi-colon in there at the end, after value2 which is invalid. I guess you intended to type a quote mark there? The semi-colon will be causing all your queries to fail and throw errors.
This may be the cause of your problem but you haven't got any error checking in there, so you won't know. Add some error checking to your code after calling the query; even if the query is right, it's still possible to get errors, and your code should check for them. See the examples on this manual page: http://www.php.net/manual/en/mysqli-stmt.error.php
Finally, since you're using the mysqli API, it's worth mentioning that your code would be a lot better and probably more secure if you used prepared statements. See the examples in PHP manual here: http://www.php.net/manual/en/mysqli-stmt.bind-param.php
[EDIT]
Another possible reason your query is failing is that you're not escaping the input values. If any of the input values contains a quote character (or any other character that is illegal in SQL) then the query will fail. In addition, this problem makes your code vulnerable to a SQL injection hacking attack.
You need to escape your input using $SQL->real_escape_string() OR by changing your query to use prepared statements (as recommended above).
Your query is inside the loop, which means that the loop will wait until your query finished executing before it continue, php code is processed in order...
Has #phpalix said, PHP goes in order, and waits for the previous action to finish.
I think you SQL is wrong. Try replacing your INSERT with this:
$query = "INSERT INTO my_table VALUES ('".$item->value1."', '".$item->value2."');";
And don't forget to run at least mysql_real_escape_string for each variable, for security measures.
As many of the answers and comments say, it does not continue until the SQL is done. The problem was in my local apache/mysql server. It was fixed by restarting it. Yes, stupid post.
I must be doing really stupid here. I've been troubleshooting this for 3 days with no luck.
Here is the PHP string that is sent to mysql_query():
insert into post_replies (postID, fromID, toID, status) values ($id, $userID, $toID, ".g_unread.")
Before you say, "Ah-hah, there must be an error in the SQL", please note these two things:
mysql_query() returns true (1)
I export the string to a text file (see below) BEFORE sending to mysql_query() - If I paste the exported text into the same mysql_query() statement, it works fine (new row appears) - If paste the exported text into phpMyAdmin, it works fine (new row appears)
The exact (and I mean exact, as in I simply copy and pasted it) same query is used a few lines down and it always works fine
Another thing I tried was to load the query back from the text and then send it to mysql_query() - but that produces the same odd behavior - it returns success (1), yet no new rows are actually inserted.
I have showed this to another programmer, who complained about my PHP coding style. He said INTs should be wrapped as strings and I should use curly braces around those (e.g. '{$id}'). However, of course that fixed nothing, the behavior was exactly the same. If there was a problem with string generation then the problem would appear in the query that is exported to text file before sending to mysql_query(). He also complained that I was using outdated mysql functions (that I should be using mysqli functions). However, that does not explain why my hundreds of other queries sent via mysql_query() work fine, including the one a few line below this one. It does not explain why the query works fine if I paste the exported-to-text-file text directly into mysql_query().
Thank you so much. I am totally lost here.
UPDATE #1: By request, here is the code around the statement:
$q = "insert into post_replies (postID, fromID, toID, status) values ($id, $userID, $toID, ".g_unread.")";
$result = mysql_query($q);
if ($result == true) {
z($q);
} else {
z('failure');
}
z() is a function I use for easily exporting to text file. Btw, the query is always sent to z(), 'failure' is never sent.
Here is an example of what is sent to the text file:
insert into post_replies (postID, fromID, toID, status) values (2039, 8, 1, 1)
Please keep mind that if I paste that text into phpMyAdmin, or into the mysql_query() function above, the row is inserted.
UPDATE #2: Due to concern by some, I have updated this part of the code to use mysql[i]
$mysqli = new mysqli(g_db_server, g_db_user, g_db_pass, g_db);
$result = $mysqli->query($q);
I now make a separate connection, just for this single query. However, the behavior is exactly the same. It returns true, but no news rows are created. However, if I export $q to a text file, and then paste that text into $mysqli->query() above, it works fine and the new row is created as expected.
Since everyone seems to have given up, I am now working on isolating the problem to single MySQL table / PHP file which anyone can download and try for themselves.
UPDATE #3: Solved! Sort of. It seems to be an issue with the surrounding code, causing the row to be deleted after insertion. However, this still doesn't explain why mysql_insert_id() returned 0. Perhaps mysql_insert_id() breaks on composite keys. Anyhow, I don't care - because it's fixed. I will give the check to #user1231958 because his answer was the closest. Thank you all immensely for your help and sorry for being tricked by mysql_insert_id()
Try to use grave accent's when specifying your tables and rows,
$q = "INSERT INTO `post_replies` (`postID`, `fromID`, `toID`, `status`) VALUES ('$id', '$userID', '$toID', '".g_unread."')";
$result = mysql_query($q);
if ($result == true) {
z($q);
} else {
z('failure');
}
Tell me if if that works.
Does mysql_error() return anything? This maybe lame, but are you connecting to the right database while performing the insert?
You could also enable query logging in mysql to record all queries. Howtogeek has an article on enabling this feature. After the server is restarted, you should start seeing all queries logged into the file you specified. Mine looks like this.
/opt/local/libexec/mysqld, Version: 5.1.61-log (Source distribution). started with:
Tcp port: 3306 Unix socket: /opt/local/var/run/mysql5/mysqld.sock
Time Id Command Argument
120727 8:57:09 1 Connect root#localhost on foo
1 Query /* test comment */ insert into test(foo) values(NOW())
1 Quit
Now that you can monitor all queries going to the mysql server, prefix your query with a comment to identify it in the log. I used the following PDO code to generate the log above.
$dbh = new PDO("mysql:host=localhost;dbname=foo",'root','');
$dbh->exec("/* test comment */ insert into test(foo) values(NOW())");
I had a problem just like this. I found the problem to be fields not having a default value.... I recently went from a Linux server to a Windows server and must have got a bit lazy while using Linux.
The problem was, when using my Linux server i don't have to put every single field into the INSERT query, for some reason (I'm not sure why) it seems to default them for me however, the Windows server I'm using does so the mysqli error function was saying no default for some fields, add these fields in and it worked fine for me.
I know this question has been answered but this might help other people having the same problem, after all i don't want someone else pulling their hair out for 3 days.
you have to check if there is something prevent committing your command,
try this command after executing the query:
mysql_query ( "COMMIT;" );
I just ran into this issue and found the problem.
If, somehow, your table doesn't have a correct auto-increment for a primary key it will return true but not actually insert the new row.
[UPDATED] with new code "sql_real_escape_string()"
[UPDATED] if anyone wants to look at the site its at Test site
[UPDATED] with the while code showing any results via echo
Hello All,
I have looked at many posts on this matter, but simply cannot understand why the following code doesn't work:
$username = $_POST['username'];
// get the record of the user, by looking up username in the database.
$query = sprintf("SELECT UserName, Password FROM userlogin WHERE UserName='%s'", mysql_real_escape_string($username));
$result = mysqli_query($dbc, $query) or
die ("Error Querying Database for: " . $query .
"<br />Error Details: " . mysql_error() . "<br/>" . $result);
while ($row = mysqli_fetch_assoc($result))
{
Echo($row['UserName']);
}
The Code seems to be correct... the database is working perfectly (for input purposes) and the connection is a shared connection applied with require_once('databaseconnection.php'); that is working for the registration side of things.
like normal I'm sure this is something simple that I have overlooked but cannot for the life of me see it!
I do not get any error messages from the myssql_error() its simply blank.
any help would be much appreciated.
Regards
Check the username you try to query as it might be empty. Do you really use a post-request to run that script? How do you verify that it does not work? What do you do with $data after the query?
If just nothing seems to happen it is likely your query did not match any record. Check for whitespace and case of the username you are looking for.
Mind those warnings:
Use a prepared statement or at least sql-escape any user-input before using it in sql.
Don't use die in serious code only for debugging.
The $data will contain a result object. You need to iterate over it using something like mysqli_fetch_assoc($data).
Also, you can interpolate variables directly into double quoted strings - i.e. UserName='".$username."'" could be written more cleanly as UserName='$username' rather than breaking out of the string.
Also, please sanitize your input - all input is evil - using mysqli_real_escape_string() function. You've got a SQL injection exploit waiting to happen here.
Bear in mind that it's a very good idea to validate all data to be inserted into a database.
Very often you have problems with query itself, not implementation. Try it in phpMyAdmin first and see if there are any problems.
Check server logs.
BY THE WAY: Never put variables from POST to query! That's definitely a SQL injection'
You might have some issue with the query.
Have you Tried to echo the $query and run that directly with mysql client or workbench?
This piece of code seems ok. That is, if $dbc contains an actual database connection. But the choice of naming that variable $data while the function actually returns a result object or a boolean, indicates that you may process the data wrong.
If that is not the problem, we'll definately have to see more code.
Try printing $data variable instead of printing only query. Check, whether you are able to get any error messages. If you could see any data then you should use mysql fetch function to iterate things. Try it.