2011-03-24 5 views
0
SELECT Tbl.*, 
      ROWNUM RN1 
     FROM 
      (
      SELECT DISTINCT(LEAVEID), 
       LEAVECODE, 
       LEAVENAME, 
       DESCRIPTION, 
       STATUS 
      FROM HRM_LEAVECONFIGURATION 
       WHERE 
       (
        (
        :LEAVENAME IS NULL OR 
        UPPER(LEAVENAME) LIKE UPPER(:LEAVENAME) 
       ) 
        AND 
        (
        :STATUS IS NULL OR 
        STATUS = :STATUS 
       ) 
        AND 
        (
        ISFIXED <> 1 OR 
        ISFIXED IS NULL 
       ) 
        AND 
        (
        :LEVECODE   IS NULL OR 
        UPPER(LEAVECODE) = UPPER(:LEVECODE) 
       ) 
       ) 
       ORDER BY(
        CASE 
         (
         SELECT t.data_type 
          FROM user_tab_columns t 
          WHERE t.TABLE_NAME = 'HRM_LEAVECONFIGURATION' AND 
          t.COLUMN_NAME = 'LEAVENAME' 
        ) 
        WHEN 'VARCHAR2' 
        THEN 'UPPER(LEAVENAME)' 
        ELSE 'LEAVENAME' 
        END) DESC 
     ) 
      Tbl 

이것은 문제가있는 코드입니다.오라클에서 쿼리 결과를 어떻게 동적으로 정렬 할 수 있습니까?

여기에서 필자는 대문자를 입력하고 싶은 필드의 데이터 형식에 따라 매개 변수로 필드 이름을 전달합니다.

예 : leavename의 데이터 유형이 varchar2 인 경우 leavename의 데이터 유형이 varchar가 아닌 경우 leavename의 데이터 유형이 varchar가 아닌 경우 상위 (leavename) 내림차순으로 정렬 한 다음 leavename 만 정렬하십시오.

여기 내 문제는이 쿼리가 작동하지만 주문하지 않습니다. 다른 제안이 있습니까?

+1

'order by'부분에서 'select'부분에 사용하는 것과 동일한 내용을 추가하여 실제 값이 무엇인지 확인할 수 있습니다. – zerkms

+0

[IS NULL OR appraoch의 성능 문제] (http://use-the-index-luke.com/sql/where-clause/obfuscation/smart-logic)로 인해 동적 SQL을 사용하도록 선택할 수도 있습니다. 이 경우 앱에서 ORDER BY 절도 결정할 수 있습니다. –

답변

1

열의 데이터 유형이 어떤 경우인지는 확실하지 않습니다. 확실히 LEAVENAME은 항상 VARCHAR2가 될 것입니까?

그래서 당신이 필요로하는 모든이입니다 :

ORDER BY(
    CASE 
     when :LEAVENAME is not null THEN UPPER(LEAVENAME) 
    ELSE LEAVENAME 
    END) DESC 

아마도 당신의 정확한 비즈니스 로직이 다른 당신은 당신이 실제로 값을 전달하는 어떤 열을 기준으로 주문합니다. 어떤 경우에는 다음과 같이 작성해야합니다.

ORDER BY(
    CASE 
     when :LEAVENAME is not null THEN UPPER(LEAVENAME) 
     when :LEVECODE is not null THEN UPPER(LEVECODE) 
    ELSE LEAVENAME 
    END) DESC 

덧붙여 말하자면 이러한 쿼리에는주의해야합니다. 그들은 옵티 마이저를 혼동합니다. 즉, 옵티 마이저가 일부 또는 실제로 항상 수행 될 수 있음을 의미합니다. 동적으로 쿼리를 어셈블하는 것이 더 나은 방법입니다.

+0

답변 해 주셔서 감사합니다. – user674251

+0

하지만 내 필요는 조금 다릅니다. ( CASE (t USER_TAB_COLUMNS WHERE t.TABLE_NAME = 'HRM_LEAVECONFIGURATION'FROM SELECT t.data_type t.COLUMN_NAME AND = 'LEAVENAME' ) 'VARCHAR2' THEN 'UPPER (LEAVENAME)' ORDER BY ELSE 'LEAVENAME' 끝) DESC – user674251

0

저는 열 이름을 바인드 할 수 없다고 확신합니다.

주문 순서는 하나의 레이어에 속합니다. 최종 세트가 아닌 선택중인 결과 세트를 정렬하고 있습니다. 정렬 기준은 쿼리가 끝날 때 마지막 Tbl 이후에 속합니다.

관련 문제