坚持创建游标
Stuck to Create Cursor
我想更新我的价值工资。
例如,如果@sex = 'F' 则只有性别为 F 的员工会被更新,其他与之前相同
ALTER procedure spEmployeeJamKerja (@sex varchar(1))
AS
BEGIN
SET NOCOUNT ON
DECLARE @temp int
DECLARE @fname nvarchar(20)
DECLARE femaleEmpCursor CURSOR FOR
SELECT e.fname, SUM(W.hours) AS TOTAL
FROM employee e, works_on w
WHERE e.sex = @sex AND e.ssn = W.ssn
GROUP BY e.ssn,e.fname
OPEN femaleEmpCursor
FETCH NEXT FROM femaleEmpCursor INTO @fname, @temp
WHILE @@FETCH_STATUS = 0
BEGIN
IF(@temp > 20)
BEGIN
UPDATE employee
SET salary = salary + (@temp*5)
WHERE sex = @sex
END
ELSE IF (@temp <= 20)
BEGIN
UPDATE employee
SET salary = salary + ((@temp-1)*4)
WHERE sex = @sex
END
END
END
CLOSE femaleEmpCursor;
DEALLOCATE femaleEmpCursor;
在我尝试我的存储过程之后,查询永远不会停止,就像一个无限循环。有什么解决这个问题的建议吗?
您没有在循环内部获取数据,所以它只是一遍又一遍地使用相同的值。只需在循环内重复您的 fetch 语句即可。
FETCH NEXT FROM femaleEmpCursor INTO @fname,@temp
WHILE @@FETCH_STATUS = 0
BEGIN
IF(@temp>20)
BEGIN
UPDATE employee
SET salary = salary + (@temp*5)
WHERE sex = @sex
END
ELSE IF (@temp<=20)
BEGIN
UPDATE employee
SET salary = salary + ((@temp-1)*4)
WHERE sex = @sex
END </pre>
FETCH NEXT FROM femaleEmpCursor INTO @fname,@temp
END
可能有更好的方法,但我认为这回答了问题。
你绝对不需要光标,有不同的基于集合的方法可以解决你的问题。这是另一种选择:
UPDATE e
SET e.salary = e.salary +
CASE
WHEN Total > 20 THEN Total*5
WHEN Total <= 20 THEN (Total -1)*4
END
FROM employee e
INNER JOIN (SELECT ssn, SUM([hours]) Total
FROM works_on
GROUP BY ssn) w
ON e.ssn = w.ssn
WHERE sex = @sex;
只是为了在此处提供另一种选择,您可以使用 cte 执行此操作的另一种方法。
with EmployeeData as
(
select SUM(W.hours) AS TOTAL
, e.ssn
from employee e
join works_on w on e.ssn = W.ssn
where e.sex = @sex
group by e.ssn
,e.fname
)
update e
set salary =
Case when ed.Total > 20
then salary + (ed.Total * )
else salary + ((ed.Total - 1) * 4)
end
from Employee e
join EmployeeData ed on ed.ssn = e.ssn
where e.sex = @sex
我想更新我的价值工资。
例如,如果@sex = 'F' 则只有性别为 F 的员工会被更新,其他与之前相同
ALTER procedure spEmployeeJamKerja (@sex varchar(1))
AS
BEGIN
SET NOCOUNT ON
DECLARE @temp int
DECLARE @fname nvarchar(20)
DECLARE femaleEmpCursor CURSOR FOR
SELECT e.fname, SUM(W.hours) AS TOTAL
FROM employee e, works_on w
WHERE e.sex = @sex AND e.ssn = W.ssn
GROUP BY e.ssn,e.fname
OPEN femaleEmpCursor
FETCH NEXT FROM femaleEmpCursor INTO @fname, @temp
WHILE @@FETCH_STATUS = 0
BEGIN
IF(@temp > 20)
BEGIN
UPDATE employee
SET salary = salary + (@temp*5)
WHERE sex = @sex
END
ELSE IF (@temp <= 20)
BEGIN
UPDATE employee
SET salary = salary + ((@temp-1)*4)
WHERE sex = @sex
END
END
END
CLOSE femaleEmpCursor;
DEALLOCATE femaleEmpCursor;
在我尝试我的存储过程之后,查询永远不会停止,就像一个无限循环。有什么解决这个问题的建议吗?
您没有在循环内部获取数据,所以它只是一遍又一遍地使用相同的值。只需在循环内重复您的 fetch 语句即可。
FETCH NEXT FROM femaleEmpCursor INTO @fname,@temp
WHILE @@FETCH_STATUS = 0
BEGIN
IF(@temp>20)
BEGIN
UPDATE employee
SET salary = salary + (@temp*5)
WHERE sex = @sex
END
ELSE IF (@temp<=20)
BEGIN
UPDATE employee
SET salary = salary + ((@temp-1)*4)
WHERE sex = @sex
END </pre>
FETCH NEXT FROM femaleEmpCursor INTO @fname,@temp
END
可能有更好的方法,但我认为这回答了问题。
你绝对不需要光标,有不同的基于集合的方法可以解决你的问题。这是另一种选择:
UPDATE e
SET e.salary = e.salary +
CASE
WHEN Total > 20 THEN Total*5
WHEN Total <= 20 THEN (Total -1)*4
END
FROM employee e
INNER JOIN (SELECT ssn, SUM([hours]) Total
FROM works_on
GROUP BY ssn) w
ON e.ssn = w.ssn
WHERE sex = @sex;
只是为了在此处提供另一种选择,您可以使用 cte 执行此操作的另一种方法。
with EmployeeData as
(
select SUM(W.hours) AS TOTAL
, e.ssn
from employee e
join works_on w on e.ssn = W.ssn
where e.sex = @sex
group by e.ssn
,e.fname
)
update e
set salary =
Case when ed.Total > 20
then salary + (ed.Total * )
else salary + ((ed.Total - 1) * 4)
end
from Employee e
join EmployeeData ed on ed.ssn = e.ssn
where e.sex = @sex