MySQL multiple statement execution order - mysql

I have created a routine which inserts a record in one table, and after that it searches for that id (with a select statement) and updates another table's field with that id.Is this possible? It's one routine so my question is if the statements are executed in a sequential order?
Thanks in advance

You do not need to search for the id. You can use LAST_INSERT_ID() to get the id of the last inserted row.
INSERT INTO tablename
(<columns>)
VALUES
(<columnvalues>);
SELECT LAST_INSERT_ID() INTO somevariable;
Then you can write your UPDATE statement.
UPDATE sometable
SET sometable.col = somevariable
WHERE sometable.something = #something
Statements in a routine are executed in the order they are written.

Related

Update and select using single query in mysql

I want to update the columns and select the values using single query in MySQL
For example
update table set address='bangalore',updated_count =updated_count+1 where id=1
select * from table where id=1
This is not possible. As #D-Shih mentioned, you cannot do both update and select in the same query. The SQL update convention doesn't allow for return data and the select statement can't write to a table.
Each has its own purpose and can't be written in one statement. They must be executed separately.

SQL check if existing row, if not insert and return it

I'm having a problem with my sql query. I need to insert a data that needs to be checked first if it is existing or not. If the data is existing the sql query must return it, if not insert and return it. I already google it but the result is not quite suitable to my problem. I already read this.
Check if a row exists, otherwise insert
How to 'insert if not exists' in MySQL?
Here is a query that' I'm thinking.
INSERT INTO #tablename(#field, #conditional_field, #field, #conditional_field)
VALUES(
"value of field"
(SQL QUERY THAT CHECK IF THERE IS AN EXISTING DATA, IF NOT INSERT THE DATA and RETURN IT, IF YES return it),
"value of feild",
(SQL QUERY THAT CHECK IF THERE IS AN EXISTING DATA, IF NOT INSERT THE DATA and RETURN IT, IF YES return it)
);
Please take note that the conditional field is a required field so it can't be NULL.
Your tag set is quite weird, I'm unsure you require all the technologies listed but as long as Firebird is concerned there's UPDATE OR INSERT (link) construction.
The code could be like
UPDATE OR INSERT INTO aTable
VALUES (...)
MATCHING (ID, SomeColumn)
RETURNING ID, SomeColumn
Note that this will only work for PK match, no complex logic available. If that's not an option, you could use EXECUTE BLOCK which has all the power of stored procedures but is executed as usual query. And you'll get into concurrent update error if two clients execute updates at one time.
You could split it out into 2 steps
1. run a select statement to retrieve the rows that match your valus. select count (*) will give you the number of rows
2. If zero rows found, then run the insert to add the new values.
Alternatively, you could create a unique index form all your columns. If you try to insert a row where all the values exist, an error will be returned. You could then run a select statement to get the ID for this existing row. Otherwise, the insert will work.
You can check with if exists(select count(*) from #tablename) to see if there is data, but with insert into you need to insert data for all columns, so if there is only #field missing, you cant insert values with insert into, you will need to update the table and go with a little different method. And im not sure, why do you check every row? You know for every row what is missing? Are you comparing with some other table?
You can achieve it using MySQL stored procedure
Sample MySQL stored procedure
CREATE TABLE MyTable
(`ID` int, `ConditionField` varchar(10))
;
INSERT INTO MyTable
(`ID`, `ConditionField`)
VALUES
(1, 'Condition1'),
(1, 'Condition2')
;
CREATE PROCEDURE simpleproc (IN identifier INT,ConditionData varchar(10))
BEGIN
IF (SELECT ID FROM MyTable WHERE `ConditionField`=ConditionData) THEN
BEGIN
SELECT * FROM MyTable WHERE `ConditionField`=ConditionData;
END;
ELSE
BEGIN
INSERT INTO MyTable VALUES (identifier,ConditionData);
SELECT * FROM MyTable WHERE `ConditionField`=ConditionData;
END;
END IF;
END//
To Call stored procedure
CALL simpleproc(3,'Condition3');
DEMO

SELECT & UPDATE at the same time - race condition

I'm experiencing a race condition because I'm dealing with a lot of concurrency.
I'm trying to combine these two mysql statements to execute at the same time.
I need to select a row and update the same one...
SELECT id_file FROM filenames WHERE pending=1 LIMIT 1;
UPDATE filenames SET pending=2 WHERE id_file=**id of select query**;
Another solution to the race-condition I'm experiencing would be to perform an UPDATE query where pending=1 and somehow get the ID of the updated row, but I'm not sure if that's even possible?
Thanks
To deal with concurrency is one of the basic functions of transactions.
Wrap your queries into one transaction and tell the DBMS, that you need the row not to change in between with FOR UPDATE:
BEGIN;
SELECT id_file FROM filenames WHERE pending=1 LIMIT 1 FOR UPDATE;
# do whatever you like
UPDATE filenames SET pending=2 WHERE id_file=**id of select query**;
COMMIT;
You can execute these statements with 4 mysqli_query calls, and do whatever you want in between, without need to worry about the consistency of your database. The selected row is save until you release it.
You can avoid the "race" condition by performing just an UPDATE statement on the table, allow that to identify the row to modified, and then subsequently retrieve values of columns from the row.
There's a "trick" returning values of columns, in your case, the value of the id_file column from the row that was just updated. You can use either the LAST_INSERT_ID() function (only if the column is integer type), or a MySQL user-defined variable.
If the value of the column you want to retrieve is integer, you can use LAST_INSERT_ID() function (which supports a BIGINT-64 value).
For example:
UPDATE filenames
SET pending = 2
, id_file = LAST_INSERT_ID(id_file)
WHERE pending = 1
LIMIT 1;
Following the successful execution of the UPDATE statement, you'll want to verify that at least one row was affected. (If any rows satisfied the WHERE, and the statement succeeded, we know that one row will be affected. Then you can retrieve that value, in the same session:
SELECT LAST_INSERT_ID();
to retrieve the value of id_file column of the last row processed by the UPDATE statement. Note that if the UPDATE processes multiple rows, only the value of last row that was processed by the UPDATE will be available. (But that won't be an issue for you, since there's a LIMIT 1 clause.)
Again, you'll want to ensure that a row was actually updated, before you rely on the value returned by the LAST_INSERT_ID() function.
For non-integer columns, you can use a MySQL user-defined variable in a similar way, assigning the value of the column to a user-defined variable, and then immediately retrieve the value stored in the user-defined variable.
-- initialize user-defined variable, to "clear" any previous value
SELECT #id_file := NULL;
-- save value of id_file column into user-defined variable
UPDATE filenames
SET pending = 2
, id_file = (SELECT #id_file := id_file)
WHERE pending = 1
LIMIT 1;
-- retrieve value stored in user-defined variable
SELECT #id_file;
Note that the value of this variable is maintained within the session. If the UPDATE statement doesn't find any rows that satisfy the predicate (WHERE clause), the value of the user-defined variable will be unaffected... so, to make sure you don't inadvertently get an "old" value, you may want to first initialize that variable with a NULL.
Note that it's important that a subsequently fired trigger doesn't modify the value of that user defined variable. (The user-defined variable is "in scope" in the current session.)
It's also possible to do the assignment to the user-defined variable within in a trigger, but I'm not going to demonstrate that, and I would not recommend you do it in a trigger.

Check if record exists delete it using mysql

i'm using MySQL and i want to check if a record exists and if it exists delete this record.
i try this but it 's not working for me:
SELECT 'Barcelone' AS City, EXISTS(SELECT 1 FROM mytable WHERE City = 'Barcelone') AS 'exists';
THEN
DELETE FROM mytable
WHERE City = 'Barcelone';
Thank you for your help.
The if statement is only allowed in stored procedures, stored functions, and triggers (in MySQL).
If I understand what you want, just do:
DELETE FROM mytable
WHERE City = 'Barcelone';
There is no reason to check for the existence beforehand. Just delete the row. If none exist, no problem. No errors.
I would recommend an index on mytable(city) for performance reasons. If you want to check if the row exists first, that is fine, but it is unnecessary for the delete.
If you mean MySQL is returning an error message (if that's what you mean by "not working for me"), then that's exactly the behavior we would expect.
That SQL syntax is not valid for MySQL.
If you want to delete rows from a table, issue a DELETE statement, e.g.
DELETE FROM mytable WHERE City = 'Barcelone'
If you want to know how many rows were deleted (if the statement doesn't throw an error), immediately follow the DELETE statement (in the same session) with a query:
SELECT ROW_COUNT()
Or the appropriate function in whatever client library you are using.
If the ROW_COUNT() function returns 0, then there were no rows deleted.
There's really no point (in terms of MySQL) in issuing a SELECT to find out if there are rows to be deleted; the DELETE statement itself will figure it out.
If for some reason your use case requires you to check whether there are rows be be deleted, then just run a separate SELECT:
SELECT COUNT(1) FROM mytable WHERE City = 'Barcelone'

query to Update another table if first update fails in mysql

I have a .sql file with some update queries.
What i am looking for is when an update query fails, i should be able to execute another update query
e.g. Update table1 set col1="zbc" where id=1;
suppose above query fails as "id=1" was not found.
Then i want to execute below query to do update on another table:
Update table2 set col1="zbc" where id=1;
Since i want this to go in .sql file, I am looking for a single query to achieve this using if/case statement or something similar.
What if just run the second query and check if these rows exist in the first table for example:
Update table1 set col1="zbc" where id=1;
Update table2 set col1="zbc" where id=1
and not exists (select id from table1 where id=1);
or use ROW_COUNT() MySql function and IF. It returns the number of rows changed, deleted, or inserted by the last statement.
Can you use a stored procedure and call that procedure from the .sql file contents? The MySQL manual states that if/then clauses are supported only in "stored programs":
http://dev.mysql.com/doc/refman/5.5/en/if.html