我已经写了一个程序,应该根据每个人的经验日来增加员工表的工资。增加的值在另一个表中。有人能告诉我为什么它不会增加工作超过3650天的员工的薪水吗?
DECLARE
row record;
row2 record;
dateDiff int;
BEGIN
FOR row IN EXECUTE 'SELECT * FROM employee'
LOOP
FOR row2 IN SELECT * FROM increases
LOOP
dateDiff := now()::date - row.empjoindate;
IF dateDiff> 3650 THEN
RAISE NOTICE '%', dateDiff;
END IF;
IF dateDiff >= row2.employment_length_from
AND dateDiff < row2.employment_length_to THEN
UPDATE employee SET empsalary = empsalary + row2.pay_rise WHERE empid = row.empid;
END IF;
END LOOP;
END LOOP;
END;
增加工资的表格如下:
id | employment_length_from | employment_length_to | pay_rise
----+------------------------+----------------------+----------
2 | 3650 | 7300 | 200
3 | 7300 | 10950 | 400
4 | 10950 | 14600 | 600
5 | 14600 | 18250 | 800
6 | 18250 | 21900 | 1000
1 | 0 | 3650 | 100
如果问题不明确,请问我问题。
表定义是: 对于员工:
Column | Type | Modifiers
-----------------+-----------------------------+-----------
empid | integer | not null
empemailaddress | character varying(255) | not null
empjoindate | date |
emplastname | character varying(255) |
emplogintime | timestamp without time zone |
empname | character varying(255) |
ispermanent | boolean | not null
empsalary | double precision |
索引:
"employee_pkey" PRIMARY KEY, btree (empid)
增加:
Column | Type | Modifiers
------------------------+------------------+-----------
id | integer | not null
employment_length_from | integer |
employment_length_to | integer |
pay_rise | double precision |
索引:
"increases_pkey" PRIMARY KEY, btree (id)
答案 0 :(得分:1)
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp;
CREATE TABLE tmp.increases
(id INTEGER NOT NULL PRIMARY KEY
, employment_length_from INTEGER NOT NULL
, employment_length_to INTEGER NOT NULL
, pay_rise double precision
);
INSERT INTO tmp.increases(id
,employment_length_from,employment_length_to,pay_rise)
VALUES
(1 , 0 , 3650 , 100)
,(2 , 3650 , 7300 , 200)
,(3 , 7300 , 10950 , 400)
,(4 , 10950 , 14600 , 600)
,(5 , 14600 , 18250 , 800)
,(6 , 18250 , 21900 , 1000)
;
CREATE TABLE tmp.employee
( empid INTEGER NOT NULL
, empemailaddress VARCHAR (255) not null
, empjoindate DATE
, emplastname VARCHAR (255)
, emplogintime TIMESTAMP WITHOUT TIME ZONE
, empname VARCHAR(255)
, ispermanent BOOLEAN NOT NULL
, empsalary DOUBLE PRECISION
);
INSERT INTO tmp.employee(empid,empemailaddress,empjoindate,emplastname,emplogintime,empname,ispermanent,empsalary)
VALUES
(1,'lutser@nocorp.com' , '1939-01-01', 'Lutser', '2011-09-30' , 'Kleine' , True, 100.0 )
, (2,'lutser@nocorp.com' , '1949-01-01', 'Prutser', '2011-10-01' , 'Grote' , True, 200.0 )
, (3,'lutser@nocorp.com' , '1959-01-01', 'Klutser', '2011-10-01' , 'Grote' , True, 200.0 )
, (4,'lutser@nocorp.com' , '1969-01-01', 'Glutser', '2011-10-01' , 'Grote' , True, 200.0 )
, (5,'lutser@nocorp.com' , '1979-01-01', 'Brutser', '2011-10-01' , 'Grote' , True, 200.0 )
, (6,'lutser@nocorp.com' , '1989-01-01', 'Mutser', '2011-10-01' , 'Grote' , True, 200.0 )
;
SELECT * FROM tmp.employee ;
-- EXPLAIN ANALYZE
UPDATE tmp.employee emp
SET empsalary = empsalary + inc.pay_rise
FROM tmp.increases inc
WHERE (now() - emp.empjoindate)
>= inc.employment_length_from * '1 day'::interval
AND (now() - emp.empjoindate)
< inc.employment_length_to * '1 day'::interval
;
SELECT * FROM tmp.employee ;
间隔和整数之间的转换可能很痛苦。上面我通过将int乘以1天的间隔来解决这个问题。现在,您可以将此片段嵌入过程/函数中。
答案 1 :(得分:0)
一个简单的UPDATE
应该:
UPDATE employee e
SET empsalary = empsalary + i.pay_rise
FROM increases i
WHERE (now()::date - e.empjoindate) >= i.employment_length_from
AND (now()::date - e.empjoindate) < i.employment_length_to;
你不需要plpgsql函数。
我会建议你在他们加注时标记行(在同一个查询中),这样你就不会意外地多次加注。
这是一个plpgsql函数,就像你要求的那样。它返回获得加薪的员工数量。
CREATE OR REPLACE FUNCTION f_raise(OUT happy_employees integer) AS
$BODY$
BEGIN
UPDATE employee e
SET empsalary = empsalary + i.pay_rise
FROM increases i
WHERE (now()::date - e.empjoindate) >= i.employment_length_from
AND (now()::date - e.empjoindate) < i.employment_length_to;
GET DIAGNOSTICS happy_employees = ROW_COUNT;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
COMMENT ON FUNCTION f_raise() IS 'Gives employees who deserve it a raise.
Returns number of happy employees.'