Oracle PL/SQL의 User Function에서 Boolean Return

Oracle 2010. 9. 10. 16:09
어떤 분이 질문을 하셔서 답변을 정리하여 올립니다.

Q> User Function으로 Boolean이 반환되는 것을 하나 만들었습니다.

     이 Function을 SELECT구문에서 직접 사용하고 싶은데 안됩니다. 이를 해결할 수 있는 방법이 없을까요?

A> 먼저 결론부터 알려드린다면, "없습니다."
 
     아래와 같이 예시를 위해서 Function을 생성하고, 이 Function을 호출해봅니다.

      -- Boolean값을 반환하는 Function을 하나 생성합니다.
      create or replace
      function test_boolean ( p_val in number ) return boolean is
      begin
            if p_val > 1 then
                 return TRUE;
            else
                 return FALSE;
            end if;
      end;  
     /

     -- Boolean 값을 반환하는 Function을 SELECT구문에서 사용해봅니다.
      select test_boolean(1) from dual;


     위와 같이 실행해보면 아래와 같은 Oracle Error Message를 접하시게 됩니다. 
     ORA-06552: PL/SQL: Statement ignored
     ORA-06553: PLS-382: 식이 잘못된 유형입니다
           

SELECT문에서는 Boolean을 반환하는 Function 자체를 아예 인지하는 못하는듯한 메세지가 나타납니다.

이에 대한 방법이 있을까 하여, Ask Tom Site를 찾아보았습니다.

많은 논쟁이 있었지만, 아래의 답변으로 정리는 될듯 합니다.

사용자 삽입 이미지
모든 내용을 보시려면 아래 URL로 가서 확인해보시기 바랍니다.
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:6263249199595


결론적으로, Function의 Return값으로 Boolean을 사용하기 보다는, Number or Character Type으로 변환시켜서

Return하도록 하는 것이 바람직하다 하겠습니다.

 -- 원천적으로 Boolean을 반환하는 Function을 수정하는 방법
      create or replace
      function test_boolean ( p_val in number ) return number is
      begin
            -- 0보다 큰 값을 True로 인지 (이 부분의 Logic은 원하는 대로 코딩하시면 될듯)
            if p_val > 0 then
                 return 1;
            else
                 return 0;
            end if;
      end;  
     /

  -- 기존에 존재하는 Boolean을 반환하는 Function을 다른 Function에서 호출하도록 우회하는 방법
      create or replace
      function test_character ( p_val in number ) return varchar2 is
      begin
            if test_boolean(1) = true then
                 return 'TRUE';
            else
                 return 'FALSE';
            end if;
      end;  
     /
:     

TISTORY에 Login하려면 여기를 누르세요.


DISTINCT May Remove Sorting From Pre-Sorted Data

Oracle 2010. 9. 10. 11:39

Distinct는 원래 Sort가 발생되도록 되어 있지만, Query 결과가 Sorted되지 않은 상태로 나오는 경우가 있습니다.

그 원인과 해결 방법에 대해서 아래와 같이 정리합니다.

이 문제는 Oracle DB Version : 10.2.0.1 ro 11.1.0.7 까지 모든 Platform에서 발생합니다.

Symptoms

Including a DISTINCT clause in a query may re-sort data into an un-sorted order. 

For  example:

select distinct username 
from ( select username 
from all_users 
order by username ) 

USERNAME 
------------------------------ 
MDSYS 
TSMSYS 
SYSMAN 
ORDPLUGINS 
ORDSYS 
SYS


Cause

Distinct does not guarantee that data will be returned in sorted order since methods that do not feature sort algorithms (such as hashing) can be used to evaluate this operation. 

All that distinct guarantees is that no duplicates will be included. If the method used to remove duplicates happens to be a sort operation then the data may be sorted, but if not the data may not be sorted. Indeed, if the data was sorted by a previous step, it may be un-sorted by a distinct operation.

Since there is no order by clause on the query block featuring the distinct, there is no requirement that the data must be returned in a sorted order.


Solution

If a sorted order is required, an order by must be included in the relevant query block.

select distinct username 
from ( select username 
from all_users 
order by username ) 
order by username;


개발할 때, 간과할 수 있는 소지가 다분한 Issue이므로 꼭 기억해야만 원하는 Data를 얻게 됩니다.


Reference : Oracle Support
:     

TISTORY에 Login하려면 여기를 누르세요.


Group By와 Distinct의 차이가 뭘까?

Oracle 2010. 9. 10. 09:45
Group By와 Distinct 모두 Select 구문과 함께 사용되면서, 중복행을 제거하기 위해서 많이들 사용합니다.

물론 Group By의 경우에는 단순히 중복행을 제거하는 기능만 있는것은 아니지만 말입니다.

Oracle 9i까지는 Distinct와 Group By 모두 Plan 상에서 Sort를 발생시킵니다.

하지만, Oracle 10g이상부터는 Group By의 경우 Sort가 Plan 상에서 없어지게 되지요.

불필요한 Sort로 성능을 저해하는 요인(?)을 제거해보겠다.... 뭐 그런 맥락인것이지요.

그럼 여기서 생기는 궁금증 하나??


▷ 단순히 중복행을 제거하기 위해서 Group By와 Distinct를 사용한다고 했을 경우 두개의 차이점은??

    적은 Data의 양을 가지고 중복행을 제거하고자 할 때는 Distinct가 빠르고,

    많은 Data의 양을 가지고 중복행을 제거하고자 할 때는 Group by가 빠르다고들 한다.

    왜일까??  


위의 문제에 대해서 좀 더 알아보아야 할 것 같다.
:     

TISTORY에 Login하려면 여기를 누르세요.