だけの答えをmasskoに追加する -
普通Cursor FOR loopは、単純、より効率的かつ明示的なopen-fetch-exit-close
よりも信頼性が高いです。また、ループ内で更新する行を指定する必要があります。そうしないと、テーブルのすべての行が更新されます。 (コンパイラはコードの配置方法やランダムな単語を大文字にするかどうかは気にしませんが、最初のリファクタとして次のようになります)。
begin
for r in (
select course_id -- Assuming courses have a unique ID
, student_number, course_price
from courses
)
loop
if r.student_number < 10 then
update courses set course_price = r.course_price * 1.05
where course_id = r.course_id;
elsif r.student_number > 10 then
update courses set course_price = r.course_price * 1.07
where course_id = r.course_id;
end if;
end loop;
end;
しかし、変更のすべてが倍率であるときにupdate
ステートメントを2回繰り返すのはなぜですか?また、何もしない行をループしているのはなぜですか?したがって、我々は、ステージ、さらにそれを簡略化することができます。私たちは一発でそれを行うことができるとき
begin
for r in (
select course_id, student_number, course_price
from courses
where student_number <> 10
)
loop
update courses
set course_price = r.course_price *
case
when r.student_number < 10 then 1.05
when r.student_number > 10 then 1.07
end
where course_id = r.course_id;
end loop;
end;
を再度、なぜ私たちも面倒行ごとのアプローチが必要なのですか?
begin
update courses c
set course_price = r.course_price *
case
when c.student_number < 10 then 1.05
when c.student_number > 10 then 1.07
end
where c.student_number <> 10;
end;
ところで私はあなたのデータモデルを知らないが、各コースレコード内の学生の数のカウントを格納することは信頼性の高いアプローチを思えません。
PL/SQL ['if'](http://docs.oracle.com/database/121/LNPLS/controlstatements.htm#LNPLS391)の条件では、' 'によって終了されているため、大括弧は不要です。チュートリアルのページの作成者が、括弧で冗長な例題を混乱させたのはなぜか謎です。おそらく彼はJavaScriptを考えていたでしょう。 –