What's wrong with my SQL Fiddle query? - mysql

Take a look at this simple query in SQL fiddle: http://sqlfiddle.com/#!2/c1eb6/1. This is a super-simple update query, why is it producing an error? I wonder if could it be a bug in that site?
Build Schema:
create table your_table (some_column varchar(50));
insert into your_table set some_column = '30# 11';
insert into your_table set some_column = '30# 12.00';
insert into your_table set some_column = '30# 13.5';
insert into your_table set some_column = 'abdfs';
insert into your_table set some_column = '0000000';
Query:
UPDATE your_table
SET some_column = 1;

A bit of background for those interested in some of the arcane issues I've been dealing with on SQL Fiddle:
Disable explicit commits in JDBC, detect them in SQL, or put the database in a readonly state (dba.se)
Essentially, I am trying to ensure that the fiddles always remain in a consistent state, even as people play with them. One thing I've worried about is people intentionally messing with the databases, breaking them for the other people that might be working with them (this has happened before, but not often fortunately).
I've found methods of keeping things clean for each of the database platforms, but interestingly each method is completely different for each platform. Unfortunately, for MySQL I had to resort to the worst option - only allowing SELECTs on the right-hand side. This is because there are too many ways to write queries that include implicit commits, and there is no way that I've found to prevent that from happening short of outright denial on the query side. This is quite unfortunate, I realize, but it seems to be required.
Anyhow, this particular bug was a result from a change I had recently made in the logic for MySQL. It is fixed now, and now reports the expected error message:
DDL and DML statements are not allowed in the query panel for MySQL;
only SELECT statements are allowed. Put DDL and DML in the schema
panel.

I got this error on SQL Fiddle because I was trying to use PostgresSql syntax, while the interpreter was set to MySql

Related

Can't specify target table for update in FROM clause - Mysql 5.7.10 - derived_merge not working

I have the following query:
update tblwerknemerdienst toUpdate
set datumtot = (select subdate(datumvanaf,1)
from (select * from tblwerknemerdienst) nextDienst
where nextDienst.Werknemer = toUpdate.Werknemer
and nextDienst.datumvanaf > toUpdate.DatumVanaf
order by DatumVanaf
LIMIT 1)
WHERE DatumTot IS NULL;
The query runs fine on MySql versions other than MySql 5.7.10. I've searched around the web and found that you have to set derived_merge=off, but sadly this had no effect and the query still fails with the same error.
I have also tried several different ways of rewriting the query, but all to no avail.
Is there something I'm missing or is there another way to accomplish this?
In the end I fixed this by rewriting the whole thing in a procedure, where I used a cursor to execute the query and get the necessary data. Then I perform the update statement based upon the fields selected in the cursor.
This seemed to be the only way to reliably perform the operation required on different versions of MySql.

PDO. Two SELECT, using BEGIN and COMMIT and get SQLSTATE[HY000]: General error

Here is query
BEGIN;
SELECT NumberRenamed, ... FROM 2_1_paidused WHERE CreditAccount = ? AND ...;
SELECT NumberRenamed, ... FROM 2_1_paidused WHERE DebitAccount = ? AND ...;
COMMIT;`
(... is long list with columns and conditions).
and get SQLSTATE[HY000]: General error.
Removed BEGIN; and COMMIT; and all works as expected without errors.
From my knowledge if more than one SELECT, then need to use BEGIN; and COMMIT; But appears that I am wrong. So, does it mean that it is allowed to use more than one SELECT without BEGIN; and COMMIT;? Or my query is incorrect?
Those are four SQL statements. You don't share any PHP code but the way you display the queries suggest that you launch them at once into a single database call. Apparently, running multiple queries in PDO is quite tricky—no idea if you got it right.
In any case, your transaction code is redundant:
PDO has builtin functions to start and commit transactions. There's no need to run commands manually.
You don't write into the database, thus transactions don't have any purpose anyway.
I'm pretty sure you just need to run your two SELECT queries separately.
Edit: perhaps you're confused with BEGIN ... END. That's an entirely different feature. In MySQL, you can only use it in the body of stored routines.

SQL Injection and the LIMIT clause

This question is to settle an argument between me and a coworker.
Let's say we have the following query, executed on a standard LAMP server.
SELECT field1, field2, field3
FROM some_table
WHERE some_table.field1 = 123
ORDER BY field2 DESC
LIMIT 0, 15
Now let's assume the limit clause is vulnerable to SQL injection.
LIMIT [insert anything here], [also insert anything here]
The point of my coworker is that there is no way to exploit this injection, so there's no need to escape it (since it take more processing power and stuff).
I think her reasoning is stupid, but I can't figure out how to prove her wrong by finding an example.
I can't use UNION since the query is using an ORDER BY clause, and the MySQL user running the query doesn't have the FILE priviledge so using INTO OUTFILE is also out of the question.
So, can anyone tell us who is right on this case?
Edit: the query is executed using PHP, so adding a second query using a semicolon won't work.
The LIMIT clause is vulnerable to SQL injection, even when it follows an ORDER BY, as Maurycy Prodeus demonstrated earlier this year:
mysql> SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1
procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
ERROR 1105 (HY000): XPATH syntax error: ':5.5.41-0ubuntu0.14.04.1'
Voilà! The above solution is based on handy known technique of so-called error based injection. If, therefore, our vulnerable web application discloses the errors of the database engine (this is a real chance, such bad practices are common), we solve the problem. What if our target doesn’t display errors? Are we still able to exploit it successfully?
It turns out that we can combine the above method with another well-known technique – time based injection. In this case, our solution will be as follows:
SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 1,1
PROCEDURE analyse((select extractvalue(rand(),
concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1)
It works. What is interesting that using SLEEP is not possible in this case. That’s why there must be a BENCHMARK instead.
I would insert this:
1; DELETE FROM some_table WHERE 1; --
Just after the limit, that will select 1 row from some_table, then DELETE all some_table rows. then the rest will be considered as a comment.
SQL Injection occurs if “externally-influenced input […] could modify the intended SQL command”. And in this case it’s clear that user input can modify the intended SQL command.
However, exploitability is another question. You may not be able to exploit it today. But maybe someday someone is able to exploit it because:
The database connection layer has changed and it is possible to execute multiple statements at once.
The statement has changed and it is possible to use UNION.
The user privileges have changed and it is possible to use INTO OUTFILE/INTO DUMPFILE.
Someone finds a way that you may not have thought of. Have you noticed you can store the result in variables and/or execute a stored procedure?
If you are creating the SQL query from user input, then it will be vulnerable, unless you are using strong typing way before you get anywhere near generating the query. In such a case, there's no way you could make an integer become text saying to drop a table, for example.
Never trust user input, and always perform bounds checking. For example, don't even bother doing the query if the limit values are negative.
You should come with a coding example, not a query example as you do now. She is right on the fact that you cannot really alter a statement since the order by function is always "last". So yes, when you are manually inputting those query's on a sql server, you simply cannot alter the query to output something different rather than a error message. Yet, when you simply add an other query.. you can :)
Finish the last user input as a true value to let the first query run successfully, and add a ';'. Now you can start your own query.
I just have done this on my local mysql server:
SELECT * FROM city order by ID desc limit 0,15; SELECT * FROM city
Even so, in a strong case where there is absolute 0% chance someone could alter the statement, you simply do not even want to receive possible altered data. There should be a reason you use the LIMIT dynamically. Once a person can change your reason, you already have failed. Its not even about risking damage, losing data or what ever. You do not want any manipulation in any way.

SQL Server : track table inserts

I have a table which get new data inserted every minute or so. According to the source code I have here, it is only done in one class which is not used anymore.
Is there any way to trace the inserts? What I mean is to see which queries they were inserted by, who sent those queries etc. As much info as possible.
I have tried several ways myself (e.g.sp_who2 'Active' stored procedure) without any success. I also have access to the machine running the SQL server and to the transaction backup files (.trn files) but have no idea how to open those files.
Add trigger to the table which follows inserts and insert to other table these variables:
getdate(),
host_name(),
App_Name(),
suser_sname()
Seems to me that this is enough
The trigger looks like this:
CREATE TRIGGER YourTrigger On YourTable
AFTER INSERT
AS
SET NOCOUNT ON;
INSERT logtable
SELECT APP_NAME(), HOST_NAME(), SUSER_SNAME(), GETDATE(), * FROM INSERTED
GO
OR
you can use Sql Server Profiler for catching the queries - it may be more flexible
You may use sp_depends like this:
sp_depends tablename
This only states information in the same database but it might say what you need!

Is it possible a trigger on a select statement with MySQL?

I know that triggers can be used on insert, update and delete, but what about a trigger (or sort of) on a select statement. I want to use a trigger to insert data on a table B when it is selected an existent record on a table A, it could be possible?.
Thanks in advance.
You should design your application so that database access occurs only through certain methods, and in those methods, add the monitoring you need.
Not exactly a trigger, but you can:
CREATE FUNCTION myFunc(...) BEGIN INSERT INTO myTable VALUES(...) END;
And then
SELECT myFunc(...), ... FROM otherTable WHERE id = 1;
Not an elegant solution, though.
It is not possible in the database itself.
However there are monitoring/instrumentation products for databases (e.g. for Sybase - not sure about MySQL) which track every query executed by the server, and can do anything based on that - usually store the query log into a data warehouse for later analysis, but they can just as well insert a record into table B for you, I would guess.
You can write an application which will be monitoring the query log and doing something when a select occurs. A pretty crude way to solve the problem though...