복붙노트

[SQL] 방법 최대 절전 모드 HQL에서 오라클의 REGEXP_LIKE를 사용 하는가?

SQL

방법 최대 절전 모드 HQL에서 오라클의 REGEXP_LIKE를 사용 하는가?

나는 오라클 10g를 사용하여 3.3.2 최대 절전 모드입니다. 나는 HQL에서 사용하고 처음으로 지금, 전 SQL에서 정규 표현식을 사용했다.

Query query = getSession().createQuery("From Company company 
where company.id!=:companyId and 
regexp_like(upper(rtrim(ltrim(company.num))), '^0*514619915$' )");

내가 예상대로 실행 REGEXP_LIKE 기능이없는 실행할 때, 내 HQL입니다. 하지만 REGEXP_LIKE 표현식을 실행할 수 없습니다입니다.

그것은 말한다 ..

친절하게 도움을, 어떻게 최대 절전 모드 기본 쿼리에 regex_like를 사용할 수 있습니까? 또는 다른 대안은 그렇게 할 수 있습니다.

해결법

  1. ==============================

    1.사실, 당신은 PL / SQL에서 조건문을 제외하고 아무것도 REGEXP_LIKE의 결과를 비교할 수 없습니다.

    사실, 당신은 PL / SQL에서 조건문을 제외하고 아무것도 REGEXP_LIKE의 결과를 비교할 수 없습니다.

    Hibernate는 항상 무언가, 즉 출력을 비교할 필요로하는 returnType이없이 사용자 정의 기능을 허용하지 같다 :

    REGEXP_LIKE('bananas', 'a', 'i') = 1
    

    오라클은 당신이 아무 것도이 함수의 결과를 비교하는 것을 허용하지 않습니다, 나는 경우 조건을 사용하여 솔루션을 함께했다 :

    public class Oracle10gExtendedDialect extends Oracle10gDialect {
    
        public Oracle10gExtendedDialect() {
            super();
            registerFunction(
              "regexp_like", new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN,
              "(case when (regexp_like(?1, ?2, ?3)) then 1 else 0 end)")
            );
        }
    
    }
    

    그리고 당신의 HQL은 다음과 같이한다 :

    REGEXP_LIKE('bananas', 'a', 'i') = 1
    

    그것은 작동합니다 :)

  2. ==============================

    2.당신은 가장 확실히 당신이 (한 Hibernate가 공급자로하고 JPQL) 최대 절전 모드 HQL과 함께하고자하는 데이터베이스의 특정 기능의 모든 유형을 사용할 수 있습니다. 당신은 단순히 그 기능에 대해 최대 절전 모드를 말해야한다. 3.3에서 그 유일한 옵션은 사용자 정의 방언을 제공하고 방언의 생성자에서 함수를 등록하는 것입니다. 당신이 기본 방언 클래스를 살펴 경우, 회원 가입 기능의 예를 많이 볼 수 있습니다. 일반적으로 가장 당신이 현재 사용하고 정확한 방언을 확장하고 간단하게 (함수를 등록, 여기에) 확장 기능을 제공합니다.

    당신은 가장 확실히 당신이 (한 Hibernate가 공급자로하고 JPQL) 최대 절전 모드 HQL과 함께하고자하는 데이터베이스의 특정 기능의 모든 유형을 사용할 수 있습니다. 당신은 단순히 그 기능에 대해 최대 절전 모드를 말해야한다. 3.3에서 그 유일한 옵션은 사용자 정의 방언을 제공하고 방언의 생성자에서 함수를 등록하는 것입니다. 당신이 기본 방언 클래스를 살펴 경우, 회원 가입 기능의 예를 많이 볼 수 있습니다. 일반적으로 가장 당신이 현재 사용하고 정확한 방언을 확장하고 간단하게 (함수를 등록, 여기에) 확장 기능을 제공합니다.

    흥미로운 노트는 오라클이 분류 REGEXP_LIKE 함수로하지 않습니다. 그들은 조건 / 술어로 분류합니다. 나는 오라클 SQL은 자신의 PL / SQL을 수행하더라도, 부울 데이터 유형을 정의하지 않습니다 내가 REGEXP_LIKE는 PL / SQL 함수를 반환 BOOLEAN으로 정의된다 내기 때문에이 대부분이라고 생각 ...

    현재 Oracle10gDialect를 사용하는 가정하면, 당신은 할 것이다 :

    public class MyOracle10gDialect extends Oracle10gDialect {
        public Oracle10gDialect() {
            super();
    
            registerFunction( 
                "regexp_like", 
                 new StandardSQLFunction( "regexp_like", StandardBasicTypes.BOOLEAN )
            );
        }
    }
    

    HQL 파서가 단독으로 술어 모든 인 측면에서 그러나 논리 값을 반환하는 기능을 좋아하면 기억이 없습니다. 대신 그 반환에 대한 뭔가 다른 체크에 충실 /의 거짓을 변환 할 수 있습니다 :

    public class MyOracle10gDialect extends Oracle10gDialect {
        public Oracle10gDialect() {
            super();
    
            registerFunction( 
                "regexp_like", 
                 new StandardSQLFunction( "regexp_like", StandardBasicTypes.INTEGER ) {
                     @Override
                     public String render(
                             Type firstArgumentType, 
                             List arguments, 
                             SessionFactoryImplementor factory) {
                         return "some_conversion_from_boolean_to_int(" + 
                                 super.render( firstArgumentType, arguments, factory ) +
                                 ")";
                     }
                 }
            );
        }
    }
    
  3. ==============================

    3.당신은 표준 LIKE 연산자를 사용하여 시도 할 수 있습니다 :

    당신은 표준 LIKE 연산자를 사용하여 시도 할 수 있습니다 :

    where company.num like '%514619915'
    

    다음 자바 정규식을 사용하여 원치 않는 사람을 필터링합니다. 즉, 반환되는 불필요한 행의 수를 줄여야합니다.

    그것이 '%'로 시작하기 때문에 인덱스를 사용하지 않을 것입니다.

  4. ==============================

    4.당신은 액세스 특정 데이터베이스 기능 JPQL / HQL하지 않는 한 그렇게 할 수있는 방법을 제공하지 않으며, 어느 쪽도 정규 표현식 아무것도 제공 할 수 없습니다. 그래서 당신은 사용 정규식에 대한 네이티브 SQL 쿼리를 작성해야합니다.

    당신은 액세스 특정 데이터베이스 기능 JPQL / HQL하지 않는 한 그렇게 할 수있는 방법을 제공하지 않으며, 어느 쪽도 정규 표현식 아무것도 제공 할 수 없습니다. 그래서 당신은 사용 정규식에 대한 네이티브 SQL 쿼리를 작성해야합니다.

    그들은 인덱싱 할 수 없기 때문에 또 다른, 매우 중요한 점에서 몇 동료 (오라클 DBA는) 전체 DB 검색을 수행하는 DB에서 끝나는, 오라클의 정규 표현식에 사용하지 않습니다 나에게 말했다. 테이블이 몇 가지 항목이있는 경우, 괜찮아요,하지만 행이 많이있는 경우, 그것은 성능을 절름발이 수 있습니다.

  5. ==============================

    5.sqlRestriction (버전 4.2.7 하이버 네이트)와 그 사용 절전 기준치

    sqlRestriction (버전 4.2.7 하이버 네이트)와 그 사용 절전 기준치

     Criterion someCriterion = Restrictions.sqlRestriction("regexp_like (column_name, ?, 'i')", "(^|\\s)"+searchValue+"($|\\s|.$)", StringType.INSTANCE);
    
  6. ==============================

    6.아니면 또 다른 옵션은 연산 결과에 따라 숫자 값을 반환합니다 오라클에서 유사한 기능을 만드는 것입니다. 뭐 그런

    아니면 또 다른 옵션은 연산 결과에 따라 숫자 값을 반환합니다 오라클에서 유사한 기능을 만드는 것입니다. 뭐 그런

    CREATE OR REPLACE FUNCTION MY_REGEXP_LIKE(text VARCHAR2, pattern VARCHAR2)
    RETURN NUMBER 
    IS function_result NUMBER;
    BEGIN
      function_result := CASE WHEN REGEXP_LIKE(text, pattern) 
      THEN 1 
      ELSE 0
      END;    
      RETURN(function_result);
    END MY_REGEXP_LIKE;
    

    당신은 사용할 수 있습니다

    MY_REGEXP_LIKE('bananas', 'a') = 1
    
  7. from https://stackoverflow.com/questions/11793159/how-to-use-oracles-regexp-like-in-hibernate-hql by cc-by-sa and MIT license