The following code gives me an error "1064 You have an error in your SQL syntax;"
$this->mysqli->query("START TRANSACTION;
UPDATE Balances
SET balance={$left}
WHERE user='{$user}';
INSERT INTO Bought (user, orderid) VALUES ('{$user}', {$id});
COMMIT;");
I just can't understand why this is happening, because every command if it's used separately from others works perfect.
Execute each part as a single query when using query(), or use multi_query()
Related
I need to insert a POINT value into my MySQL table using Fat Free Framework. I was hoping to do this using the F3 Mapper, but I got the impression that is not possible.
So I tried to use $db-exec()
This is my current code, based on various searches here and on google.
$geopoint = "POINT($lat $long)";
$db->exec("INSERT INTO event_dates ('eventGeoPoint') VALUES ($geopoint)");
This throws an error:
PDOStatement: 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 '52.8583742))' at line 1
I have also tried
$db->exec("INSERT INTO event_dates ('eventGeoPoint') VALUES (GeomFromText($geopoint))");
Please tell me how to correctly insert a POINT() value into my database using Fat Free Framework, either the mapper or exec
You need to correct your INSERT statement, which you are mixed with UPDATE statement.
INSERT INTO mytable SET myGeoPoint = 'GeomFromText($geopoint)
should be
INSERT INTO mytable(myGeoPoint) values (GeomFromText($geopoint))
Also, you need to use Prepared Statement to avoid SQL Injection.
Searching on after #Ravi's comments I found the answer in this post.
I changed my statement to
$result= $db->exec("INSERT INTO mytable (GeoPoint) VALUES (PointFromText(CONCAT('POINT(',$lat,' ',$long,')')))");
And it works!
Firstly, I know that this system shouldn't be using mysql_ functions anymore, but it does.
The system is connecting to two databases. Before running a query, it is selecting the correct database on which to run the query using mysql_select_db(). The correct database is 'database2'. The connection to the database itself works, and the mysql_select_db function is returning true/1.
The code works locally but does not work on the server...
Here is an example of a failing query...
global $DBtwo;
mysql_select_db('database2', $DBtwo);
$sql = "INSERT INTO table
(Column1, Column2, Column3)
VALUES
('Value1', 'Value2', 'Value3')";
$result = mysql_query($sql, $DBtwo);
die(mysql_error());
This script returns the following output...
Table 'database1.table' doesn't exist
The error suggests that the query is being executed on database1, not database2. However database2 is being successfully selected before the query is run.
As mentioned, this error only occurs on the server. Running locally the queries work and the correct databases are used.
Any suggestions or pointers would be very welcome. Cheers.
The comment from Marc B solved my problem so credit goes to him.
The mysql_error function was returning misleading info as it was not being passed a resource.
The mysql_select_db was actually working. It gave the impression of not working via a combination of not passing the correct resource to mysql_error. On top of that a mysql_insert_id() was not working for the same reason, leading the function overall to return false.
I now feel stupid, but far less annoyed. Many thanks!
I wrote some code that built up a single query of multiple insert and update statements which was executed at the end of a page load. It used to work okay. I am writing similar, optimised code on my dev system (Ubuntu 14.04, PHP 5.5.3-Ubuntu), but I am no longer able to run multiple statements in one PDO query:
What I do
During a page render, I build up an SQL statement that would look a bit like:
insert into <table> (col1,col2,col3) VALUES (?,?,?);
update <table> set col1 = ?, col4 = ? where id = ?;
insert into <table> (col1,col2,col3) VALUES (?,?,?);
...
When the page has been rendered and I'm sure there are no problems, I execute the query using a wrapper for PDO. The important bits of the wrapper function are
$database = new PDO("mysql:host=<host>;dbname=<dbname>", <user>, <pwd>,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names 'utf8'"));
$database->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $database->prepare($sql);
$stmt->execute($params);
For some reason, I am no longer able to execute this statement in one hit, instead, PDO only performs the first query, despite $stmt->queryString still holding the whole query. Can anyone help me with this problem.
Found the problem:
PDO fails silently if one of the queries throws an exception. In my case, the first query was okay, but the second was throwing an integrity constraint failure error, so it looked like only the first query was being run.
A wise man just told me: Don't shoot the messenger, break the queries up
I've found somewhere in the code where a string isn't being escaped properly. I've been trying to see if it is exploitable (don't worry, I'll end up escaping it or using prepared statements anyway, this is just for a learning experience).
This is using mysqli->query() function;
The Query is generated in PHP like so:
$Query = "CALL some_proc(".$_SomeID.",'".$_UnescapedString."')";
By inputting $_UnescapedString as test'); DROP TABLE SomeTable; -- I got the query:
CALL some_proc(1, 'test'); DROP TABLE SomeTable; -- ')
This query was successfully run but it seems that it didn't run the second query. I tested this by putting invalid SQL in the second query and got no errors. I assume this means mysqli is smart enough to only execute a single query?
Now my question is, can I somehow inject SQL into the stored procedure itself? Here is the procedure:
BEGIN
SELECT COUNT(*) AS SomeCount
FROM DataTable
WHERE DataTable.SomeID = _SomeID
AND DataTable.SomeValue LIKE CONCAT('%',_UnescapedString,'%');
END
I've tried various SQL such as test','%')-- to see if the query would carry on as normal, but it only changes the stored procedure call, i.e:
CALL some_proc(1, 'test', '%')--');
Is there anyway to get a DROP TABLE command into _UnescapedString?
Disclaimer, I use SQL Server and not mySQL, but assuming the behavior with regards to parameters in stored procedures is the same, and also assuming that _UnescapedString is an input parameter, putting DROP TABLE in the parameter would look like this:
SELECT COUNT(*) AS SomeValue
FROM DataTable
WHERE DataTable.SomeID = _SomeID
AND DataTable.SomeValue LIKE '%DROP TABLE%');
With regards to the query:
CALL some_proc(1, 'test'); DROP TABLE SomeTable; -- ')
Maybe the DROP TABLE command did not execute due to the user account under which you are running having insufficient permissions to execute DDL statements?
Restricting the permissions of the user account being used to access the database from the web server is a way to limit the damage that an SQL Injection attack could cause. However, it won't stop them.
I have a PHP foreach loop and a mysql insert statement inside of it. The loop inserts data into my database. I've never ran into this issue before but what I think is happening is that the insert dies (I do not have an "or die" statement after the insert) when it reaches a duplicate record. Even though there may be duplicate records in the table, I need this to just continue. Is there something that I need to specify to do this?
I'm transferring some records from one table to another. Right now, I have 20 records in table #1 and only 17 in table #2. I'm missing 3 records but only one of those are duplicated which violates the constraint on the table. The other two records should have been added. Can someone give me some advice here?
What's happening is that PHP is throwing a warning when the mysql insert fails and stopping on that warning. The best way to accomplish your goal is:
Create a custom exception handler
Set PHP to use the exception handler for warnings.
Wrap the insert attempt into a try / catch
When you catch the exception / warning, either log or output the mysql error but continue script execution.
This will allow your script to continue without stopping while at the same time explaining to you the problem.
One way around this would be to simply query the database for the record that you're about to insert. This way, your series of queries will not die when attempting to insert a duplicate record.
A slightly more efficient solution would be to query for [i]all[/i] of the records you're about to insert in one query, remove all the duplicates, then insert the new ones.
Do you insert multiple rows with one INSERT statement?
INSERT INTO xyz (x,y,z) VALUES
(1,2,3),
(2,3,5),
(3,4,5),
(4,5,6)
Then you might want to consider prepared statements
...or adding the IGNORE keyword to your INSERT statement
INSERT IGNORE INTO xyz (x,y,z) VALUES
(1,2,3),
(2,3,5),
(3,4,5),
(4,5,6)
http://dev.mysql.com/doc/refman/5.0/en/insert.html says:
If you use the IGNORE keyword, errors that occur while executing the INSERT statement are treated as warnings instead
You can still fetch the warnings but the insertion will not be aborted.
Not a good way cause you should figure out whats wrong, but to just prevent it from dieing try adding # in front of the function
#mysql_query = ...
INSERT INTO FOO
(ID, BAR)
VALUES(1,2),(3,4)
ON DUPLICATE KEY UPDATE BAR=VALUES(BAR)