update field using datediff - mysql

i have been trying to update a with the number of days using datediff.
The following statement works fine:
select DATEDIFF (date_stock_out,date_stock_in) from paddock
But when I try to update the third field in the table with the following statement, I am getting a syntax error:
update paddock set number_of_days = select DATEDIFF(date_stock_out,date_stock_in) from paddock
Where am I going wrong.
Thanks for any assistance

Normally you do an UPDATE without having a SELECT right in the middle of it:
UPDATE paddock SET number_of_days=DATEDIFF(date_stock_out,date_stock_in)
It's implied you're working on paddock so there's no need to repeat yourself.
SQL statements each have their own unique syntax and restrictions on how, where and when they can be used. Check carefully before composing them together like you would functions in other more flexible programming languages.

Related

MySQL UPDATE statement is throwing "Column count doesn't match value count" error

(NOTE: I know this is an error that's commonly asked about, but most of the time, the issue is in an INSERT statement. I couldn't find a question on this website where this error happened during an UPDATE.)
I have a table in MySQL (InnoDB / v. 5.7.19) called RESULTS which has, among others, two columns called TYPE and STATUS. Both are of type ENUM, with PASS, FAIL and IGNORE being the supported values in both. I'm trying to run this UPDATE statement on that table, using Workbench (also tried the same directly on the DB machine, using the mysql command):
update `RESULTS` set `TYPE`='IGNORE' where `STATUS`='IGNORE';
I'm getting this error:
Error Code: 1136. Column count doesn't match value count at row 1
Changing the single quotes to double quotes didn't help. I'm able to run this query successfully:
select count(`TYPE`) from `RESULTS` where `STATUS`='IGNORE';
I'm probably making a silly mistake here, but can anyone point out what's wrong with the UPDATE statement?
As requested I am posting it as an answer.
The error basically is self-explanatory like performing an operation on set of attributes but the values provided in the query are not enough. But in your case, you are performing an update operation with all attributes and their values and still, this error appears it may be a case that there is some trigger is registered for this table probably on before/after the event, If that is the case you need to update or remove that trigger if no needed.

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.

MySQL Update multiple tables query syntax

I'm trying to update two tables in MySQL with one query, and am running into an error. I've looked at similar situations and resolutions, but can't seem to translate them to my specific query/situation as I am continuing to get the same error. My goal seems like there is an obvious solution I am missing. My Query is as follows:
UPDATE table_pr, table_pu
INNER JOIN table_pu ON table_pr.id = table_pu.pr_id
SET table_pr.cpr2 = table_pu.cpr2_id, table_pu.cpr_updated = '1'
WHERE table_pu.cpr2_date < CURRENT_DATE()
When I run the Update, I get Not unique table/alias: 'table_pu' returned. I prefer to not use aliases in this, but I've also tried to set unique aliases for the tables with the same result. If my approach should be modified, my ultimate goal is to have table_pr.cpr2 set to table_pu.cpr2_id based on WHERE table_pu.cpr2_date < CURRENT_DATE() and if the update is run, to also set table_pu.cpr_updated = '1'
Any help or guidance would be greatly appreciated.
Removing the second table reference in the UPDATE statement resolved the issue.

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.

How can I sum two fields and store the result in a third field on a MySQL table autonomously?

I created a simple UPDATE AFTER INSERT trigger to sum two DECIMAL(10,2) fields and update a 3rd DECIMAL(10,2) field with the summed value.
The trigger code is:
delimiter |
CREATE TRIGGER calc_ttl_cost AFTER INSERT ON buybox_rec
FOR EACH ROW
BEGIN
UPDATE buybox_rec SET total_cost = (price+shipping_cost);
END;
|
I'm using phpMyAdmin to run the SQL commands, so I know that the trigger is being created successfully. Furthermore, if I run the UPDATE buybox_rec SET total_cost = (price+shipping_cost); SQL statement alone, it works as expected. (I've also tried the same code with back-ticks around the field names, but I wouldn't be writing all this if that worked)
The problem is that when I insert a new row, the trigger doesn't work and this error is thrown:
#1442 - Can't update table 'buybox_rec' in stored function/trigger
because it is already used by statement which invoked this stored
unction/trigger.
The error seems like some sort of recursive or circular reference problem, but I can't figure out where/what the problem is.
I also tried creating a stored procedure and calling it from within the trigger to try obtaining the same result, but I got the same error.
I checked a bunch of other SO questions related to MySQL UPDATE triggers and did some Googling, but here I am.
Is this out of the scope of MySQL? It seems like such a common and easy task to allow for.
Does anyone know how I accomplish this task autonomously? (AKA I don't want to hear about summing the fields after the fact via PHP, for example)
THanks for any help
The problem is that you're trying to modify the contents of a table which is already being used by the UPDATE + TRIGGER operation. This simply can't be done, but you have alternatives.
For example, if your meaningful data (or independent variables) are price and shipping cost while the total cost depends on them, you could keep only the first two in your table, and maybe have a very simple VIEW (something like SELECT price, shipping_cost, price+shipping_cost total_cost FROM buybox_rec, or whichever other fields you need) if you want to keep an eye at the total.