mysql: Can I use an Case Expression to execute other statements? - mysql

SET #Count = '2';
SELECT CASE #Count
WHEN 1 THEN INSERT INTO customer (First_Name) VALUES (John)
WHEN 2 THEN INSERT INTO customer (First_Name) VALUES (Mary)
ELSE INSERT INTO customer (First_Name) VALUES (Ray)
END;
--this is a mysql case expression. Can I use it to execute other mysql statements like this? Actually want to execute a block of statements depending on the value of #count

You can move the logic within a single statement:
insert into customer(firstname)
select case #Count
when 1 then 'John'
when 2 then 'Mary'
else 'Ray'
end
Alternatively, you want a case statement rather than a case expression:
case #Count
when 1 then insert into customer(firstname) values('John');
when 2 then insert into customer(firstname) values('Mary');
else insert into customer(firstname) values('Ray');
end case;

Related

MySQL Stored Procedure Case Statement Syntax Error

I'm trying to create a stored procedure that calculates the amount by multiplying the ordered quantity & the rate of the product from different tables called Rate and getting Quantity from the Bookings Table.After calculating I want it to be inserted into another Table 'Amount'. I am having totally 5 products. If for example product = 'abc', then put amount for 'abc' and insert zero for the rest of the products' amount. Herein, I am using a Case Statement which throws syntax error. Kindly please offer me your help.
DELIMITER $$
CREATE PROCEDURE `calculate_amount` (IN IN_book_id INT,IN IN_qty INT )
-- begin
BEGIN
-- declare
DECLARE prdct VARCHAR(10);
DECLARE cust_id INT(5);
-- select into
SELECT Product FROM Bookings WHERE Book_id=IN_book_id INTO prdct;
SELECT Cust_id FROM Bookings WHERE Book_id=IN_book_id INTO cust_id;
-- conditionals & action
CASE prdct
WHEN "20ltr"
THEN INSERT INTO Amount(Cust_id,Book_id,Can,300ml,500ml,1lit,2lit) VALUES(cust_id,IN_book_id,(SELECT Rate.Can*Bookings.Qty FROM Rate,Bookings WHERE Bookings.Book_id=IN_book_id),0,0,0,0);
WHEN "300ml"
THEN INSERT INTO Amount(Cust_id,Book_id,Can,300ml,500ml,1lit,2lit) VALUES(cust_id,IN_book_id,0,(SELECT Rate.300ml*Bookings.Qty FROM Rate,Bookings WHERE Bookings.Book_id=IN_book_id),0,0,0);
WHEN "500ml"
THEN
INSERT INTO Amount(Cust_id,Book_id,Can,300ml,500ml,1lit,2lit) VALUES(cust_id,IN_book_id,0,0,(SELECT Rate.500ml*Bookings.Qty FROM Rate,Bookings WHERE Bookings.Book_id=IN_book_id),0,0);
WHEN "1ltr"
THEN
INSERT INTO Amount(Cust_id,Book_id,Can,300ml,500ml,1lit,2lit) VALUES(cust_id,IN_book_id,0,0,0,(SELECT Rate.1lit*Bookings.Qty FROM Rate,Bookings WHERE Bookings.Book_id=IN_book_id),0);
WHEN "2ltr"
THEN
INSERT INTO Amount(Cust_id,Book_id,Can,300ml,500ml,1lit,2lit) VALUES(cust_id,IN_book_id,0,0,0,0,(SELECT Rate.2lit*Bookings.Qty FROM Rate,Bookings WHERE Bookings.Book_id=IN_book_id));
ELSE
BEGIN
END;
END CASE;
-- end
END;$$
DELIMITER ;
In SQL (in general), CASE is not used for program conditional flow, it is used to return singular values in variable assignment. MySQL does allow it but I recommend to avoid using it as other database systems don't support it
Typical scenarios:
--doing varied logic:
name = CASE
WHEN num = 1 THEN 'one'
WHEN othernum = 2 THEN 'two'
END
--testing a single variable for being equal to values:
name = CASE num
WHEN 1 THEN 'one'
WHEN 2 THEN 'two'
END
Avoid this:
CASE
WHEN num = 1 THEN name = 'one'
WHEN num = 2 THEN name = 'two'
END
If you're after keeping your database skills cross portable, essentially the only thing you should put inside the "result" of a case is a value, not a statement
IF ELSEIF ELSE is used for conditional program flow in major databases, the MySQL docs for it are here:
https://dev.mysql.com/doc/refman/8.0/en/if.html
As another aside, prefer use of ' for strings, not " - double quotes are another MySQL deviation from standard

Use Case statement inside if else block in mysql triggers

I am new to the mysql triggers.
Let assume if i have a table name teachers contains
teacher_id,
teacher_name,
description,
student_id,
class,
student_year
I want to create a AFTER INSERT and AFTER UPDATE triggers on teachers table.
for that i have a table name called teacherslogs with id,teacher_id,student_year,class,student_id columns
so whenever record insert into teachers table it should insert into teacherslogs.(for this trigger able to write)
But for after update trigger facing issue.
Requirement:
whenever student_id changed in teachers table we need to insert a record into teacherslogs with along another columns changes in the teachers table for that record
for this i have written like this
IF ((NEW.student_id <=> OLD.student_id) = 0) Then
select student_id,class,student_year into student_id_,class_,year_ from `employees`.`teachers` where teacher_id = OLD.teacher_id;
Insert into `employees`.`teacherlogs`(teacher_id,student_year,class,student_id) values (OLD.teacher_id,year_,class_,student_id_);
END IF;
But whenever changes in other columns like class,student_year we need to update the teacherslogs table for that record where teacher_id and student_id
Final Trigger Query
create trigger `updateteacherlogs`
AFTER UPDATE ON `employees`.`teacher` FOR EACH ROW
BEGIN
DECLARE teacher_id_ int(11);
Declare student_id_ int(11);
Declare class_ varchar(150);
Declare year_ int(11);
Declare dummy tinyint;
IF ((NEW.student_id <=> OLD.student_id) = 0) Then
select student_id,class,student_year into student_id_,class_,year_ from `employees`.`teachers` where teacher_id = OLD.teacher_id;
Insert into `employees`.`teacherlogs`(teacher_id,student_year,class,student_id) values (OLD.teacher_id,year_,class_,student_id_);
ELSE
CASE WHEN (NEW.student_year <=> OLD.student_year) = 0
THEN update `teacherlogs` set student_year = NEW.student_year where student_id=OLD.student_id and teacher_id = OLD.teacher_id;
WHEN (NEW.class <=> OLD.class) = 0
THEN update `teacherlogs` set class = NEW.class where student_id=OLD.student_id and teacher_id = OLD.teacher_id
ELSE select #dummy END
end if;
END
But i am getting an exception at end if.
is that correct way to solve my problem or any other ways can we do?
The reason for your syntax error is that your CASE statement needs to end in END CASE;, not just END.
I don't think that the CASE statement actually works for your requirements though as if NEW.student_year <=> OLD.student_year then NEW.class will not get compared against OLD.class to see if that value also needs to be updated. That is because (from the manual):
For the second syntax, each WHEN clause search_condition expression is
evaluated until one is true, at which point its corresponding THEN
clause statement_list executes
You can get around that by just replacing the ELSE CASE ... with an ELSEIF clause:
ELSEIF NEW.student_year <=> OLD.student_year OR NEW.class <=> OLD.class THEN
UPDATE teacherlogs
SET student_year = NEW.student_year, class = NEW.class
WHERE student_id = OLD.student_id AND teacher_id = OLD.teacher_id;
This should work because (based on my understanding from your question of how your database is configured) the value of student_year and class in teacherlogs should be the same as OLD.student_year and OLD.class and if they are the same as NEW.student_year and NEW.class the values won't get updated.
If my understanding is incorrect, you will need modify the update to have conditions on each value:
ELSE
UPDATE teacherlogs
SET student_year = IF(NEW.student_year <=> OLD.student_year, NEW.student_year, student_year),
class = IF(NEW.class <=> OLD.class, NEW.class, class)
-- repeat for all columns
WHERE student_id = OLD.student_id AND teacher_id = OLD.teacher_id;
END IF;

How to translate an UPDATE WHERE IF ##ROWCOUNT == 0 query from MS SQL to MySQL?

I have a query in the following form:
UPDATE TableName SET some="1", fields="two"
WHERE some_condition="true"
IF ##ROWCOUNT=0 INSERT INTO TableName(some, fields) VALUES ("1", "two");
This query was written in MS SQL but I'd like to translate it to MySQL. I've looked up several refs that say to replace ##ROWCOUNT with ROW_COUNT() but I'm not sure what to do.
Any ideas of how to translate queries like this from MS SQL to MySQL?
A more elegant way of handling this would be something like....
IF EXISTS(SELECT 1 FROM TableName WITH (UPDLOCK, HOLDLOCK)
WHERE some_condition= "true" )
BEGIN
UPDATE TableName
SET some = "1"
, fields = "two"
WHERE some_condition= "true" ;
END
ELSE
BEGIN
INSERT INTO TableName(some, fields) VALUES ("1", "two");
END

SQL query with variable ,IF & select staement

How can I create an SQL select query to return variable as true(1) if a column value exists in a table else false(0).
I want to use this variable in my scripts so that
if variable=1
execute A
ELSE
execute B
In Oracle you can use something like this
SELECT
CASE nvl(length(column1), 0)
WHEN 0 THEN 0
ELSE 1
END AS column1
FROM yourTableName;
You can try this...
IF ((SELECT COUNT(*) FROM TableName WHERE FieldName = 'Whatever') <> 0)
-- Execute something if column value exists
ELSE
-- Execute something if column value does not exist
SELECT CASE WHEN EXISTS(SELECT 1 FROM tableName WHERE fieldName='value') THEN 1;
ELSE 0;
END
INTO variable
--that is PostgreSQL

Setting a variable to a list of strings for IN statement

Can I assign a list of strings to a variable for use in an IN statement without using Dynamic SQL?
I am developing a report in SSRS which allows the user to select one of three possible values as a parameter which in turn will assign values associated with that choice to an IN statement. Some parameters have a single value associated and some have several.
Cases 1 and 2 run properly, but case 3 does not because it is passed as a scalar value instead of a list. I have tried various ways of escaping the quotes around each item, but it does not work.
declare #items as varchar(50)
set #items =
CASE #parameter
WHEN 1 then 'first'
WHEN 2 then 'second'
WHEN 3 then 'third, fourth'
END
select column1
from table1
where column1 IN (#items)
No, you can not. You can use table variable in following way:
DECLARE #table TABLE(item varchar(50))
IF #parameter = 3
BEGIN
INSERT INTO #table(item) VALUES ('third'), ('fourth')
END
ELSE
BEGIN
INSERT INTO #table VALUES(
CASE #parameter
WHEN 1 then 'first'
WHEN 2 then 'second'
END
)
END
-- And use IN(subquery)
SELECT column1
FROM table1
WHERE column1 IN (SELECT item FROM #table)
Also you can use EXISTS which much faster in such condition checks but you won't get significant performance improvements due to a small items cound (1-2)
SELECT column1
FROM table1 t
WHERE EXISTS (SELECT * FROM #table WHERE item = t.column1)
you could go with dynamic sql (not tested)
declare #items as varchar(50)
set #items =
CASE #parameter
WHEN 1 then '''first'''
WHEN 2 then '''second'''
WHEN 3 then '''third'', ''fourth'''
END
declare #query = 'select column1 from table1 where column1 IN ('+#items+')'
exec #query
triple quotes are due to string concatenation mechanism