LoginSignup
1
1

More than 1 year has passed since last update.

【oracle備忘録】NVLの使い方を誤った話

Posted at

※この記事は、初心者プログラマの私が、業務で扱った内容に関連した箇所を
自身の学習用にまとめたものです。

<やりたいこと>

・テーブル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;
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1