2016-05-09 3 views
0

私の給料を更新したい。例えばカーソルの作成に固執

私は、ストアドプロシージャを試した後@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; 

前と同じである場合、クエリが停止したことがありません、無限ループのように。これを解決するための提案はありますか?

+0

これにはいくつか問題がありますが、どうしてこのような理由で「カーソル」を使用するのですか? – Lamak

+0

各従業員の勤務時間が異なるので、私はDB @Lamak – Student

+0

のすべての従業員の給与を更新するためにこれを使用します。カーソルは完全には不要です。更新で従業員名を使用していないこともわかります。毎回その性別の一人の従業員(これは正しい方法ですが、カーソルは全くありません) – Lamak

答えて

1

ループ内でフェッチしていないので、同じ値を何度も繰り返し使用しています。ループ内で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 

おそらくもっと良い方法がありますが、これは質問に答えると思います。

+0

ありがとうございました@ChrisSteeke – Student

+0

しかし、このためにカーソルは必要ありません。それは、ループを導入することによって、不必要に遅いものになった単一の更新ステートメントです。そして、それはそれぞれ通過するテーブルのすべての行を更新します。 –

2

あなたはこのためにカーソルを絶対に必要としません。あなたの問題を解決するためのさまざまなセットベースの方法があります。 1つの代替方法があります:

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; 
+0

ありがとうございました、それは有用です、私はちょうどsqlserverと私の知識が十分ではない学習... – Student

0

ここで別のオプションを提供するために、これを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 
関連する問題