※この記事は、初心者プログラマの私が、業務で扱った内容に関連した箇所を
自身の学習用にまとめたものです。
##<やりたいこと>
・テーブルA.カラムa = 引数a
・テーブルA.カラムb = 引数b
を満たすレコードが存在するとき、変数cにテーブルA.カラムcを代入。
存在しないとき、変数cに'0'を代入し、変数cを返すファンクションを作成したい。
##<登場する項目>
・テーブルA
・テーブルA.カラムa
・テーブルA.カラムb
・テーブルA.カラムc
・引数a
・引数b
・変数c
##間違えたソース
FUNCTION GET_VAL_C(
引数a IN VARCHAR2 -- 引数aの型を定義
, 引数b IN VARCHAR2 -- 引数bの型を定義
) RETURN VARCAR2
IS
変数c VARCHAR2; -- 変数cの型を定義
BEGIN
SELECT NVL(T01.カラムc, '0') -- T01.カラムcがNULLなら'0'、NULL以外ならT01.カラムcを変数cへ代入
INTO 変数c
FROM (SELECT カラムc
FROM テーブルA
WHERE カラムa = 引数a
AND カラムb = 引数b)T01;
RETURN 変数c;
END GET_VAL_C;
###◆間違えたポイント
FROMの括弧内のWHERE条件を満たさない場合、
FROM で参照するテーブルがNULLになってしまう。
(参照するテーブルがNULLということは、参照するレコードが存在しないということ)
NVLは、カラムの値のNULL判定であるため、レコード自体がNULLの場合は使用できない。
##修正後のソース
FUNCTION GET_VAL_C(
引数a IN VARCHAR2 -- 引数aの型を定義
, 引数b IN VARCHAR2 -- 引数bの型を定義
) RETURN VARCAR2
IS
変数c VARCHAR2; -- 変数cの型を定義
件数 NUMBER; -- 件数の型を定義
BEGIN
-- WHERE条件で絞った場合のテーブルAのレコード数を件数へ代入
SELECT COUNT(*)
INTO 件数
FROM テーブルA
WHERE カラムa = 引数a
AND カラムb = 引数b;
-- 上記の条件で抽出したレコード数が0の場合、変数cに'0'を代入
IF 件数 = 0 THEN
変数c := '0';
-- 上記条件で抽出したレコードが存在すれば、テーブルA.カラムcを変数cへ代入
ELSE
SELECT T01.カラムc
INTO 変数c
FROM (SELECT カラムc
FROM テーブルA
WHERE カラムa = 引数a
AND カラムb = 引数b)T01;
END IF;
RETURN 変数c;
END GET_VAL_C;