**问题是:如果他们加班,计算小时工资。您应该使用40小时的基础并支付一半的时间。我现在的代码只需按小时工资计算小时数,我现在需要将工资与按小时工资分开前40小时。然后剩下的时间乘以每小时付费时间1.5,这只有两个人idno 2222和7777. **
我的代码是:
SET SERVEROUTPUT ON
DECLARE
v_idno paydata4.idno%TYPE;
v_name paydata4.name%TYPE;
v_sal paydata4.salary%TYPE;
v_job paydata4.jobcode%TYPE;
v_pay paydata4.payhr%TYPE;
v_idno1 paytran1.idno%TYPE;
v_hourswk paytran1.hourswk%TYPE;
v_hours allinfo1.hours%TYPE;
v_nothing number(4);
CURSOR paydata4_cursor IS
SELECT idno, name, salary, jobcode, payhr FROM paydata4
ORDER BY idno;
CURSOR paytran1_cursor IS
SELECT idno, hourswk FROM paytran1
WHERE v_idno = idno
order by idno;
BEGIN
OPEN paydata4_cursor;
LOOP
FETCH paydata4_cursor INTO v_idno, v_name, v_sal, v_job, v_pay;
EXIT WHEN paydata4_cursor%NOTFOUND;
IF paytran1_cursor%ISOPEN THEN
CLOSE paytran1_cursor;
END IF;
IF v_job = 'S'THEN
v_sal := v_sal / 52;
End if;
OPEN paytran1_cursor;
v_hours := 0;
loop
if v_hours <= 40 AND v_job = 'H' THEN
v_sal := v_pay * v_hours;
END IF;
if v_hours > 40 AND v_job = 'H' THEN
v_sal := v_pay * 40;
END IF;
if v_hours > 40 AND v_job = 'H' THEN
v_pay := v_pay * 1.5;
END IF;
FETCH paytran1_cursor INTO v_idno1, v_hourswk;
EXIT WHEN paytran1_cursor%NOTFOUND;
v_hours := v_hours + v_hourswk;
dbms_output.put_line('The current amount is: '||v_hours);
END LOOP;
INSERT into allinfo1
VALUES(v_idno, v_name, v_hours, v_job, v_sal, v_nothing);
CLOSE paytran1_cursor;
END LOOP;
CLOSE paydata4_cursor;
END;
/
SET SERVEROUTPUT OFF
输出为:
SQL> select *
2 from allinfo1;
IDNO NAME HOURS JO PAY OTPAY
---- --------------- ---------- -- ---------- ----------
1111 Ann French 45 S 1442
2222 Robert Costa 61 H 2700
3333 Linda Ames 40 H 2000
4444 Scott Brooks 43 S 1500
5555 Susan Ash 40 S 1096
6666 James Smith 44 S 1058
7777 Mary Jones 45 H 1440
8888 John Morse 40 H 1560
参考表:
SQL> select *
2 from paydata4;
IDNO NAME J SALARY PAYHR
---- ------------------------- - ---------- ----------
1111 Ann French S 75000 0
2222 Robert Costa H 0 45
3333 Linda Ames H 0 50
4444 Scott Brooks S 78000 0
5555 Susan Ash S 57000 0
6666 James Smith S 55000 0
7777 Mary Jones H 0 36
8888 John Morse H 0 39
预期输出为:
SQL> select *
2 from allinfo1;
IDNO NAME HOURS JO PAY
---- --------------- ---------- -- ----------
1111 Ann French 45 S 1442
2222 Robert Costa 61 H 3218
3333 Linda Ames 40 H 2000
4444 Scott Brooks 43 S 1500
5555 Susan Ash 40 S 1096
6666 James Smith 44 S 1058
7777 Mary Jones 45 H 1710
8888 John Morse 40 H 1560
答案 0 :(得分:2)
不要过于复杂。你的计算只需要在40岁以上的所有时间增加额外的半薪吗?
所以,一旦你有了工资和工时,你只需
v_sal := (v_pay * v_hours) + ((v_pay * 0.5) * GREATEST(0, v_hours - 40));
如果v_hours&lt; 40第二个条款将结束为v_pay * 0.5 * 0 = 0
答案 1 :(得分:1)
你真的需要PL / SQL块吗?所有这些工作只能通过以下一个语句来完成:
insert into allinfo1 (idno, name, hours, jo, pay)
select p1.idno, p1.name, p1.jobcode, p1.payhr,
-- here you calculate how much to pay
case when jobcode = 'H' and p1.payhr > 40 then ...
when jobcode = 'H' and p1.payhr < 40 then ...
...
else ... end pay
from paydata4 p1, paytran1 p2
where p1.idno = p2.idno;
这不是您需要的确切代码,因为它很难理解,您的代码会做什么。但是如果你详细解释(表格,列和公式),我可以更正我的代码。
答案 2 :(得分:0)
我会尝试回答你的问题。
CAVEAT:我目前无权访问SQL会话,因此无法访问 测试语法等,您可能需要自己调试。答案 旨在为您指明正确的方向。另外,你的例子 有很多问题,比如你似乎插入了六个值 allinfo1但是当你从中选择*时,你只能获得五列 返回等
无论如何,试试这个作为起点。
为了提高效率,我已将您的游标转换为一个游标,并使用COUNT(hourswk)
,以防paytran1
表可以为每个idno
创建多个条目。
我使用了光标记录来保存结果,而不是为了管理而创建许多变量。
SET SERVEROUTPUT ON
DECLARE
--
v_hours allinfo1.hours%TYPE;
v_sal paydata4.salary%TYPE;
--
jobcode_exception EXCEPTION;
--
CURSOR pay_cursor
IS
SELECT idno,
pd4.name,
pd4.salary,
pd4.jobcode,
pd4.payhr,
SUM(pt1.hourswk) AS hours_worked
FROM paydata4 pd4
JOIN paytran1 pt1 USING (idno)
GROUP BY idno,
pd4.name,
pd4.salary,
pd4.jobcode,
pd4.payhr
ORDER BY idno;
--
BEGIN
-- Loop through pay_cursor
FOR pay_rec IN pay_cursor
LOOP
-- Check job type
CASE pay_rec.jobcode
WHEN 'S'
THEN
-- Just divide salary by 52
v_sal := v_sal / 52;
WHEN 'H'
THEN
-- Calculate overtime
IF pay_rec.hours_worked <= 40
THEN
-- Just pay standard rate
v_sal := pay_rec.payhr * v_hours;
ELSIF pay_rec.hours_worked > 40
THEN
-- Pay standard rate for first 40 hours
v_sal := pay_rec.payhr * 40;
-- Plus the overtime beyond 40 hours (overtime rate * hours over 40)
v_sal := v_sal + ((pay_rec.payhr * 1.5) * (pay_rec.hours_worked - 40));
END IF;
ELSE
-- Raise an error
RAISE_APPLICATION_ERROR(-20001, 'Error: Unexpected job code "'||pay_rec.jobcode||'" for idno: '||pay_rec.idno);
END;
-- Insert the result into the allinfo1 table
INSERT into allinfo1 VALUES(pay_rec.idno, pay_rec.name, pay_rec.hours_worked, pay_rec.jobcode, v_sal);
END LOOP;
-- Commit the inserts (remove if commit is hapeneing elsewhere)
COMMIT;
EXCEPTION
WHEN others
THEN
-- Rollback the inserts?
ROLLBACK;
-- Re-raise the error
RAISE;
END;
/
SET SERVEROUTPUT OFF