update the salary base on onther table - plsqldeveloper

I have two tables first one is emp(emp_id,name,gender--M or F) and second one is emp_sal(emp_id,address,salary).I want to update salary filed like female employee should be increment 10% and male employee should be increment 15% of current salary

We can try with the below query.....
UPDATE empd es set es.E_salary=case
when(select eg.gender from emps eg where eg.empid=es.empid)='M'
THEN
es.E_salary*0.1
else
es.E_salary*0.5
end;

DECLARE
CURSOR cur_emp
IS
SELECT * FROM emp;
rec_emp cur_emp%rowtype;
BEGIN
OPEN cur_emp;
LOOP
FETCH cur_emp INTO rec_emp;
EXIT WHEN cur_emp%notfound;
IF rec_emp.gender = 'F'THEN
UPDATE emp_sal SET sal = sal + (sal * 0.1) WHERE emp_id = rec_emp.emp_id;
elsif rec_emp.GENDER = 'M' THEN
UPDATE emp_sal SET sal = sal + (sal * 0.15) WHERE emp_id = rec_emp.emp_id;
END IF;
END LOOP;
CLOSE cur_emp;

Related

SQL query for insertion multiple data using for loop

My data set
Tabel Name Users
unique_id uid
123487.1 1000
123488.1
123489.1
123490.1
As shown above this is my existing data and i want to add uid, so my data should be displayed as shown below.
unique_id uid
123487.1 1000
123488.1 1001
123489.1 1002
123490.1 1003
You don't need cursors for this. Just do an update:
select #u := max(user_id)
from users;
update users
set user_id = (#u := #u + 1)
where user_id is null
order by unique_id;
Providing that uid value is the only a single value in your data set, you can use that simple query:
select unique_id, first_value(uid) over(order by unique_id) + row_number() over(order by unique_id) - 1 fv from users;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=d8102c3ef394d304eefa9d42b5a479ba
Best regards.
You can create a procedure like this:
CREATE PROCEDURE uid_update()
BEGIN
DECLARE Done_c INT;
DECLARE v_min_id INT;
declare number_plus int;
declare v_cur int;
DECLARE curs CURSOR FOR
select ROW_NUMBER() OVER (order by unique_id) rn
from testTable
where uid is null;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET Done_c = 1;
SELECT max(uid) INTO number_plus FROM testTable;
OPEN curs;
SET Done_c = 0;
REPEAT
FETCH curs INTO v_cur;
select min(unique_id) into v_min_id
from testTable
where uid is null;
update testTable
set uid = number_plus + v_cur
where uid is null
and unique_id = v_min_id ;
commit;
UNTIL Done_c END REPEAT;
CLOSE curs;
END
And then call that procedure like this:
call uid_update;
The values will then be updated as you asked for.
Here is the DEMO.

error 1329 (02000): no data - zero rows fetched, selected, or processed

I am getting an error in the following code below. The error is #1329 - No data - zero rows fetched, selected, or processed. What exactly does this mean and what is it that i am doing incorrectly? Thanks
create or replace procedure grade()
begin
declare no,s1,s2,s3,cnt,i,per int(20);
declare c1 cursor for select roll,sub1,sub2,sub3 from student;
set i=0;
select count(*) into cnt from student;
open c1;
while i<=cnt do
fetch c1 into no,s1,s2,s3;
set per=s1+s2+s3/3;
if per>=90 then
update student set grade='A+' where roll=no;
elseif (per<90 and per>=80)then
update student set grade='A' where roll=no;
elseif (per<80 and per>=70)then
update student set grade='B+' where roll=no;
elseif (per<70 and per>=60)then
update student set grade='B' where roll=no;
elseif (per<60 and per>=50)then
update student set grade='C+' where roll=no;
elseif (per<50 and per>=40)then
update student set grade='C' where roll=no;
else
update student set grade='FAIL' where roll=no;
end if;
set i=i+1;
end while;
close c1;
end$$
This logic:
set i = 0;
select count(*) into cnt from student;
while i <= cnt do
is going through the loop 1 extra time. It is on the last trip through the loop that you are getting the error.
If cnt is 3, for instance, then the loops are:
0
1
2
3
You either want:
set i = 1
or alternatively
while i < cnt
In SQL, I would use the first method, because things usually start counting at 1 rather than 0 in SQL -- but they are equivalent.

Update Whole Table adding value from previous row

Table acc
If I Edit "A" Amount to 100 then Total amount change
whole table need to update...
So What Will be the mysql query for updating whole table by adding (credit) or subtracting (debit) from previous total amount...
As commented by #Gordon Linoff, you can archive your goal using AFTER UPDATE trigger and a loop. I wrote up the idea as below for example.
DELIMITER //
CREATE TRIGGER acc_after_update
AFTER UPDATE
ON acc FOR EACH ROW
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE type varchar(10);
DECLARE total_amount DEFAULT 0;
DECLARE name varchar(10)
DECLARE amount INT;
DECLARE cur1 CURSOR FOR SELECT name, type, amount FROM acc;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
REPEAT
FETCH cur1 INTO name, type, amount;
IF NOT done THEN
CASE type
WHEN 'credit' THEN = total_amount + amount;
WHEN 'debit' THEN total_amount = total_amount - amount
END CASE
UPDATE acc
SET amount = total_amount
WHERE name = #name --not sure about this syntax
END IF;
UNTIL done END REPEAT;
CLOSE cur1;
END; //
DELIMITER ;
Hope this helps.
CREATE VIEW [dbo].[vSales]
AS
SELECT ROW_NUMBER() OVER(ORDER BY s.[Name] ) AS 'RowNo',
s.*
, CASE WHEN Type = 'Credit' THEN Amount ELSE - 1 * Amount END As NewAmount
FROM dbo.Sales AS s
GO
SELECT a.[RowNo],
a.[Name],
SUM(b.[NewAmount])
FROM dbo.vSales AS a INNER JOIN dbo.vSales AS b ON a.[RowNo] >= b.[RowNo]
GROUP BY a.[RowNo], a.[Name]
dbo.Sales is the table that holds all the values

MYSQL loop in function not working

I have a mysql function which will change records accordingly . But loop only execute for one time and leaves loop with this condition. "IF v_finished =1 THEN
LEAVE get_stock;
END IF;"
However its is supposed to execute multiple time. Like in my test case 3 times
BEGIN
DECLARE P_stock int(11);
DECLARE P_product int(11);
DECLARE V_From_warehouse int(11);
DECLARE V_To_warehouse int(11);
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE V_To_warehouse_stock int(11);
DECLARE V_From_warehouse_stock int(11);
declare cur1 cursor for
SELECT material_transfer_details.product_id , material_transfer_details.quantity FROM
material_transfers,
material_transfer_details
WHERE
material_transfers.id = material_transfer_details.mtm_id
AND
material_transfers.status = 'Y'
AND
material_transfers.id = V_MTM_id;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
SELECT warehouse_from INTO V_From_warehouse FROM material_transfers WHERE id =V_MTM_id;
SELECT warehouse_to INTO V_To_warehouse FROM material_transfers WHERE id =V_MTM_id;
OPEN cur1;
get_stock: LOOP
IF v_finished =1 THEN
LEAVE get_stock;
END IF;
fetch cur1 into P_product , P_stock;
SELECT quantity INTO V_To_warehouse_stock from stocks where warehouse_id = V_To_warehouse and product_id = P_product;
SELECT quantity INTO V_From_warehouse_stock from stocks where warehouse_id = V_From_warehouse and product_id = P_product;
IF (V_To_warehouse_stock IS NOT NULL)
THEN
UPDATE
stocks SET quantity = quantity - P_stock
WHERE
warehouse_id = V_to_warehouse
AND
product_id = P_product;
ELSE
INSERT INTO stocks(product_id , warehouse_id , quantity ,status, created_datetime , updated_datetime) values
(P_product , V_to_warehouse , 0-P_stock , 'Y', sysdate() , sysdate());
END IF;
IF (V_From_warehouse_stock IS NOT NULL)
THEN
UPDATE
stocks SET quantity = quantity + P_stock
WHERE
warehouse_id = V_from_warehouse
AND
product_id = P_product;
ELSE
INSERT INTO stocks(product_id , warehouse_id , quantity ,status, created_datetime , updated_datetime) values
(P_product , V_from_warehouse , P_stock , 'Y', sysdate() , sysdate());
END IF;
SET P_stock = 0;
SET P_product = 0;
END LOOP get_stock;
CLOSE cur1;
UPDATE material_transfers SET Status = 'N' WHERE id= V_MTM_id;
UPDATE material_transfer_details SET Status = 'N' WHERE mtm_id = V_MTM_id;
return '00000';
END
Two things:
First, change your code.
get_stock: LOOP
SET v_finished = FALSE;
fetch cur1 into P_product , P_stock;
IF v_finished =1 THEN
LEAVE get_stock;
END IF;
Since you are doing other things that could trip the handler, reset v_finished, then fetch from the cursor, and only then test whether to leave the loop.
As written, if you hadn't tripped the handler prematurely, you would have been testing in entirely the wrong place and would have stayed in the loop too long.
Next... be sure you understand SELECT ... INTO. I don't think it does quite what you think it does.
A scalar subquery is a much safer solution:
SET V_To_warehouse_stock = (SELECT quantity from stocks where warehouse_id = V_To_warehouse and product_id = P_product);
If SELECT ... INTO returns no rows, the variable's value does not change. It retains its former value, if one exists, and that is rarely what you expect.
Spooky action at a distance like this is best avoided, and it's an easy trap to fall into, in a loop.
See examples of this effect at https://dba.stackexchange.com/a/35207/11651.

mysql loop error in syntax

I am trying to use simple loop in mysql using Heidisql using the following syntax.
BEGIN
loop_label: LOOP
IF #number_title > #max THEN
**LEAVE loop_label;**
END IF;
select #number_title as number_distinct_title,count(*) as total from (
select count(distinct ctitle), customer_id
FROM table
GROUP BY customer_id
HAVING count(distinct ctitle)=#number_title
ORDER BY customer_id) as total ;
SET #number_title = #number_title + 1;
END LOOP
END
I get a syntax error at LEAVE loop_label;
Can someone please help?
Thanks
In MySQL when you define a trigger or procedure, you usually have to change the delimiter temporarily, because statements within the trigger/procedure must be terminated with ';'.
Just enclose the complete block in "--/" and "/" and you should be good
--/
BEGIN
loop_label: LOOP
IF #number_title > #max THEN
**LEAVE loop_label;**
END IF;
select #number_title as number_distinct_title,count(*) as total from (
select count(distinct ctitle), customer_id
FROM table
GROUP BY customer_id
HAVING count(distinct ctitle)=#number_title
ORDER BY customer_id) as total ;
SET #number_title = #number_title + 1;
END LOOP
END
/
Found from Here