Oracle SQL 関数 : BITAND,BITOR,BITXOR : ビット演算

 numberRet := BITAND( numberSrc1, numberSrc2 );

 BITAND 関数は numberSrc1, numberSrc2 の数値をビット毎に AND 処理した値を返します。
  numberSrc1, numberSrc2 のどちらかが NULL の場合は NULL を返します。

以下に BITAND 関数の例を示します。

SQL> SET NULL /NULL/
SQL> SELECT
  2    BITAND( BIN_TO_NUM(0,1), BIN_TO_NUM(0,0) ) AS "01 AND 00"
  3   ,BITAND( BIN_TO_NUM(0,1), BIN_TO_NUM(0,1) ) AS "01 AND 01"
  4   ,BITAND( BIN_TO_NUM(0,1), BIN_TO_NUM(1,1) ) AS "01 AND 11"
  5   ,BITAND( BIN_TO_NUM(1,1), BIN_TO_NUM(1,0) ) AS "11 AND 10"
  6   ,BITAND( BIN_TO_NUM(1,1), NULL )            AS "11 AND NULL"
  7  FROM DUAL;

 01 AND 00  01 AND 01  01 AND 11  11 AND 10 11 AND NULL
---------- ---------- ---------- ---------- -----------
         0          1          1          2 /NULL/


標準関数には BITOR , BITXOR 関数は存在しません。
そこで UTL_RAW パッケージを利用することで疑似的に BITAND 関数の様な処理ができます。
以下に UTL_RAW パッケージの BIT_OR 関数を利用する例を示します。

SQL> SELECT
  2    UTL_RAW.CAST_TO_BINARY_INTEGER(
  3      UTL_RAW.BIT_OR(UTL_RAW.CAST_FROM_BINARY_INTEGER(1), UTL_RAW.CAST_FROM_BINARY_INTEGER(0))) AS "01 OR 00"
  4   ,UTL_RAW.CAST_TO_BINARY_INTEGER(
  5      UTL_RAW.BIT_OR(UTL_RAW.CAST_FROM_BINARY_INTEGER(1), UTL_RAW.CAST_FROM_BINARY_INTEGER(1))) AS "01 OR 01"
  6   ,UTL_RAW.CAST_TO_BINARY_INTEGER(
  7      UTL_RAW.BIT_OR(UTL_RAW.CAST_FROM_BINARY_INTEGER(1), UTL_RAW.CAST_FROM_BINARY_INTEGER(3))) AS "01 OR 11"
  8   ,UTL_RAW.CAST_TO_BINARY_INTEGER(
  9      UTL_RAW.BIT_OR(UTL_RAW.CAST_FROM_BINARY_INTEGER(3), UTL_RAW.CAST_FROM_BINARY_INTEGER(2))) AS "11 OR 10"
 10   ,UTL_RAW.CAST_TO_BINARY_INTEGER(
 11      UTL_RAW.BIT_OR(UTL_RAW.CAST_FROM_BINARY_INTEGER(3), UTL_RAW.CAST_FROM_BINARY_INTEGER(3))) AS "11 OR 11"
 12  FROM DUAL;

  01 OR 00   01 OR 01   01 OR 11   11 OR 10   11 OR 11
---------- ---------- ---------- ---------- ----------
         1          1          3          3          3

上の例のビットの OR 処理を行う UTL_RAW.BIT_OR 関数は2個の RAWデータ型 データが引数です。
そのため UTL_RAW.CAST_FROM_BINARY_INTEGER 関数で、数値を UTL_RAW パッケージで扱うデータ型である RAWデータ型 に変換します。

以下に BIT_XOR 関数を利用する例を示します。

SQL> SELECT
  2    UTL_RAW.CAST_TO_BINARY_INTEGER(
  3      UTL_RAW.BIT_XOR(UTL_RAW.CAST_FROM_BINARY_INTEGER(1), UTL_RAW.CAST_FROM_BINARY_INTEGER(0))) AS "01 XOR 00"
  4   ,UTL_RAW.CAST_TO_BINARY_INTEGER(
  5      UTL_RAW.BIT_XOR(UTL_RAW.CAST_FROM_BINARY_INTEGER(1), UTL_RAW.CAST_FROM_BINARY_INTEGER(1))) AS "01 XOR 01"
  6   ,UTL_RAW.CAST_TO_BINARY_INTEGER(
  7      UTL_RAW.BIT_XOR(UTL_RAW.CAST_FROM_BINARY_INTEGER(1), UTL_RAW.CAST_FROM_BINARY_INTEGER(3))) AS "01 XOR 11"
  8   ,UTL_RAW.CAST_TO_BINARY_INTEGER(
  9      UTL_RAW.BIT_XOR(UTL_RAW.CAST_FROM_BINARY_INTEGER(3), UTL_RAW.CAST_FROM_BINARY_INTEGER(2))) AS "11 XOR 10"
 10   ,UTL_RAW.CAST_TO_BINARY_INTEGER(
 11      UTL_RAW.BIT_XOR(UTL_RAW.CAST_FROM_BINARY_INTEGER(3), UTL_RAW.CAST_FROM_BINARY_INTEGER(3))) AS "11 XOR 11"
 12  FROM DUAL;

 01 XOR 00  01 XOR 01  01 XOR 11  11 XOR 10  11 XOR 11
---------- ---------- ---------- ---------- ----------
         1          0          2          1          0


UTL_RAW.BIT_OR 関数及び UTL_RAW.BIT_XOR 関数を利用して BITAND 関数の様な BITOR BITXOR を宣言してみます。

SQL> CREATE OR REPLACE FUNCTION BITOR (
  2      InNum1      IN  NUMBER
  3     ,InNum2      IN  NUMBER
  4  )
  5  RETURN NUMBER
  6  IS
  7      WK1  RAW(16);
  8      WK2  RAW(16);
  9  BEGIN
 10      WK1 := UTL_RAW.CAST_FROM_BINARY_INTEGER(InNum1);
 11      WK2 := UTL_RAW.CAST_FROM_BINARY_INTEGER(InNum2);
 12      RETURN  UTL_RAW.CAST_TO_BINARY_INTEGER( UTL_RAW.BIT_OR(WK1, WK2) );
 13  END;
 14  /

ファンクションが作成されました。

SQL> SELECT
  2    BITOR( BIN_TO_NUM(0,1), BIN_TO_NUM(0,0) ) AS "01 OR 00"
  3   ,BITOR( BIN_TO_NUM(0,1), BIN_TO_NUM(0,1) ) AS "01 OR 01"
  4   ,BITOR( BIN_TO_NUM(0,1), BIN_TO_NUM(1,1) ) AS "01 OR 11"
  5   ,BITOR( BIN_TO_NUM(1,1), BIN_TO_NUM(1,0) ) AS "11 OR 10"
  6   ,BITOR( BIN_TO_NUM(1,1), BIN_TO_NUM(1,1) ) AS "11 OR 11"
  7  FROM DUAL;

  01 OR 00   01 OR 01   01 OR 11   11 OR 10   11 OR 11
---------- ---------- ---------- ---------- ----------
         1          1          3          3          3


BITXOR 関数の宣言は以下の様になります。

SQL> CREATE OR REPLACE FUNCTION BITXOR (
  2      InNum1      IN  NUMBER
  3     ,InNum2      IN  NUMBER
  4  )
  5  RETURN NUMBER
  6  IS
  7      WK1  RAW(16);
  8      WK2  RAW(16);
  9  BEGIN
 10      WK1 := UTL_RAW.CAST_FROM_BINARY_INTEGER(InNum1);
 11      WK2 := UTL_RAW.CAST_FROM_BINARY_INTEGER(InNum2);
 12      RETURN  UTL_RAW.CAST_TO_BINARY_INTEGER( UTL_RAW.BIT_XOR(WK1, WK2) );
 13  END;
 14  /

ファンクションが作成されました。

SQL> SELECT
  2    BITXOR( BIN_TO_NUM(0,1), BIN_TO_NUM(0,0) ) AS "01 XOR 00"
  3   ,BITXOR( BIN_TO_NUM(0,1), BIN_TO_NUM(0,1) ) AS "01 XOR 01"
  4   ,BITXOR( BIN_TO_NUM(0,1), BIN_TO_NUM(1,1) ) AS "01 XOR 11"
  5   ,BITXOR( BIN_TO_NUM(1,1), BIN_TO_NUM(1,0) ) AS "11 XOR 10"
  6   ,BITXOR( BIN_TO_NUM(1,1), BIN_TO_NUM(1,1) ) AS "11 XOR 11"
  7  FROM DUAL;

 01 XOR 00  01 XOR 01  01 XOR 11  11 XOR 10  11 XOR 11
---------- ---------- ---------- ---------- ----------
         1          0          2          1          0