FRUITSテーブルを作成します。
CREATE TABLE fruits (fruit_name varchar2(30));
テーブルにデータを入力します:バナナ5個、リンゴ7個、ブルーベリー3個。
INSERT INTO fruits VALUES ( 'banana' );<br> INSERT INTO fruits VALUES ( 'banana' );<br> INSERT INTO fruits VALUES ( 'banana' );<br> INSERT INTO fruits VALUES ( 'banana' );<br> INSERT INTO fruits VALUES ( 'banana' );<br> INSERT INTO fruits VALUES ( 'apple' );<br> INSERT INTO fruits VALUES ( 'apple' );<br> INSERT INTO fruits VALUES ( 'apple' );<br> INSERT INTO fruits VALUES ( 'apple' );<br> INSERT INTO fruits VALUES ( 'apple' );<br> INSERT INTO fruits VALUES ( 'apple' );<br> INSERT INTO fruits VALUES ( 'apple' );<br> INSERT INTO fruits VALUES ( 'blueberry' );<br> INSERT INTO fruits VALUES ( 'blueberry' );<br> INSERT INTO fruits VALUES ( 'blueberry' );
関数が何回起動されたかを知るために、シーケンスを作成します。
CREATE SEQUENCE seq START WITH 1;
フルーツの色(入力パラメーター)を返し、その操作のインジケーターとしてシーケンスをインクリメントする関数を作成します。
CREATE OR REPLACE FUNCTION get_colour (p_fruit_name IN varchar2)<br> RETURN varchar2<br> IS <br>l_num number;<br> BEGIN <br> SELECT seq.nextval INTO l_num FROM dual;<br><br> CASE p_fruit_name<br> WHEN 'banana' THEN RETURN 'yellow' ;<br> WHEN 'apple' THEN RETURN 'green' ;<br> WHEN 'blueberry' THEN RETURN 'blue' ;<br> END CASE ;<br> END get_colour;<br>/
テーブル内の各果物の色を調べる
SELECT get_colour(fruit_name) FROM fruits;
質問:このリクエストは何を返しますか?
SELECT seq.nextval FROM dual;
したがって、テーブルには15のエントリがあります。つまり、関数は15回呼び出されます。 そして、 seq.nextvalを実行するため、結果は16になると予想できます。別の実験のためにシーケンスをリセットしましょう。
DROP SEQUENCE seq;<br>
CREATE SEQUENCE seq START WITH 1;<br>
また、関数を使用してテーブル内の果物の色を取得しますが、今回は式SELECT FROM dualでそれをラップします。
SELECT ( SELECT get_colour(fruit_name) FROM dual)<br> FROM fruits;
質問:今回のリクエストは何を返しますか?
SELECT seq.nextval FROM dual;
前回と同様に、関数は15回実行され、リクエストは16を返すと想定されますが、そうではありません。
数値4が返されることがわかります。つまり、関数が3回だけ呼び出されたことを意味します。
どうしたの?
各テーブルエントリ(15個の果物)を渡すのに、関数が3回しか実行されないのはなぜですか。一般に、クエリは正しいデータを返します。
答えは、サブクエリの結果をキャッシュするメカニズム- スカラーサブクエリキャッシングにあります。
SELECTクエリsome_function(x)FROM dualの結果は、パラメーターxの各値に対して保存されます。
したがって、実際には、関数は異なる入力パラメーターに対してのみ実行されます。 フルーツは3種類(バナナ、リンゴ、ブルーベリー)しかありません。
関数は3回だけ実行されます。
そして、ここでトム・カイトがそれについて語っています。
ご注意 翻訳者。
完全を期すために 、この関数をDETERMINISTICとして宣言する可能性に言及してから、リクエストで
SELECT get_colour(fruit_name)FROMフルーツ; 3回のみ実行されます。