All thing of the world!

Oracle BIN_TO_NUM 설명 : 오라클 함수 본문

IT/Oracle DBMS

Oracle BIN_TO_NUM 설명 : 오라클 함수

WorldSeeker 2021. 3. 30. 21:13

1. 함수의 목적
    
    Oracle BIN_TO_NUM은 비트 벡터를 해당 숫자로 변환한다.
   
2. 샘플을 통한 개념 퀵뷰

SELECT BIN_TO_NUM(1,0,1,0)
FROM DUAL;

BIN_TO_NUM(1,0,1,0)
-------------------
10

3. 사용방법

4. 함수 PARAMETER 설명

[expr]
비트 벡터의 비트를 나타낸다. 
숫자 데이터 유형 또는 NUMBER로 변환 될 수있는 숫자가 아닌 데이터 유형을 인수로 취할 수 있다.
각 expr은 0 또는 1 이여야하며, 이 함수는 NUMBER 타입으로 반환한다.
BIN_TO_NUM은 데이터웨어하우스 응용 프로그램에서 GROUPING SET을 사용한 MATERIALIZED VIEW로부터 추출하고자 하는 집합을 SELECT하는데 유용하다.


5. 다양한 샘플표현

example 1) 비트 0에 해당하는 숫자는?

SELECT BIN_TO_NUM(0) FROM DUAL;

BIN_TO_NUM(0)
-------------
            0


example 2) 비트 0, 1에 해당하는 숫자는?

select bin_to_num(0,1) from dual;

BIN_TO_NUM(0,1)
---------------
              1


example 3) 비트 0,0,1에 해당하는 숫자는?

select bin_to_num(0,0,1) from dual;

BIN_TO_NUM(0,0,1)
-----------------
                1


example 4) 0,1 비트보다 큰 숫자가 들어가면 에러가 난다.

select bin_to_num(2,1,1) from dual;

select bin_to_num(2,1,1) from dual
                              *
1행에 오류:
ORA-01428: '2' 인수가 범위를 벗어났습니다


example 5) BIN_TO_NUM과 BITAND를 활용하여 한개의 값으로 다중 상태값 관리

order테이블의 order_status컬럼은 있고, 주문상품의 현재 위치구분(창고/우체국:), 배송방법구분(육로/항공), 수령인구분(주문자본인/대리인)을 관리하고 있다고 가정하자.

값을 넣을때는 pl/sql로 아래와 같이 넣고 있다고 가정하자.

DECLARE
    warehouse NUMBER := 1;
    ground NUMBER := 1;
    insured NUMBER := 1;
   result NUMBER;
BEGIN
    SELECT BIN_TO_NUM(warehouse, ground, insured) INTO result FROM DUAL;
    UPDATE orders SET order_status = result WHERE order_id = 2441;
END;

BIN_TO_NUM(warehouse, ground, insured)에 창고에 있다면  창고에 있다면 warehouse 비트를 켜서 1로 입력하고, 육로배송이라면 ground 비트를 켜서 1로 입력하는 방식이다.
정의상 창고에 있다면 창고의 비트인 첫번째 비트를 켠 1,0,0비트로 십진수 4가 될 것이고, 육로배송이라면 0,1,0비트로 십진수 2가 될 것이고, 수령자가 본인이라면 0,0,1비트로 십진수 1이 될 것이다.
 
그럼 order_status 값 1개로 어떻게 다중값을 추출해 낼 수 있을까?

아래와 같은 쿼리로 추출이 가능하다.

SELECT order_id, customer_id, order_status,
DECODE(BITAND(order_status, 4), 4, 'Warehouse', 'PostOffice') "Location",
DECODE(BITAND(order_status, 2), 2, 'Ground', 'Air') "Method",
DECODE(BITAND(order_status, 1), 1, 'Insured', 'Certified') "Receipt"
FROM orders;

BITAND가 핵심이다. (BITAND는 두 인자값으로 받은 숫자를 비트벡터로 풀어서 BITWISE연산을 하는 함수다)
DECODE(BITAND(order_status, 4), 4, 'Warehouse', 'PostOffice') "Location"를 예로 설명하면, 4의 비트벡터는 1,0,0이다. 그럼으로 order_status의 값이 어떤 값이 들어오든 첫번째 비트만 1이라면 창고에 있는 상태와 같다는 얘기가 된다. 
Method도 마찬가지로 2의 비트벡터는 0,1,0이 되고, order_status가 어떤 값이 들어오던지 두번째 비트만 1이 된다면 육로배송이 된다.

위 쿼리의 결과는 아래와 같다.

 

Comments