복붙노트

[SQL] ORA-01795에 대한 해결 방법이 있습니까 : 목록에서 표현의 최대 수 1000 오류가?

SQL

ORA-01795에 대한 해결 방법이 있습니까 : 목록에서 표현의 최대 수 1000 오류가?

해결 방법에 대한이 있습니까

'ORA-01795은 : 목록에있는 식의 최대 수는 1000 오류입니다'

나는 쿼리를 가지고 있고 그것은 하나 개의 필드의 값에 따라 선택 필드입니다. 나는에 절을 이용하고 있고 10000 개 값이있다

예:

select field1, field2, field3 
from table1 
where name in 
(
'value1',
'value2',
...
'value10000+'
);

목록에서 표현의 최대 수 1000 오류입니다 : 내가 쿼리를 실행할 때마다 나는 ORA-01795 얻을. 나는 두꺼비, 차이가 없습니다, 동일한 오류에 쿼리를 실행하려합니다. 어떻게 작업에 얻을 수있는 쿼리를 수정할 것인가?

미리 감사드립니다

해결법

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

    1.단지 주변이 얻을 수-조항의 배수를 사용합니다

    단지 주변이 얻을 수-조항의 배수를 사용합니다

    select field1, field2, field3 from table1 
    where  name in ('value1', 'value2', ..., 'value999') 
        or name in ('value1000', ..., 'value1999') 
        or ...;
    
  2. ==============================

    2.나는 최근에이 문제에 달려 함께 추가 IN 절을 묶는없이 그 일의 건방진 방법을 알아 냈어

    나는 최근에이 문제에 달려 함께 추가 IN 절을 묶는없이 그 일의 건방진 방법을 알아 냈어

    당신은 튜플의 사용을 만들 수

    SELECT field1, field2, field3
    FROM table1
    WHERE (1, name) IN ((1, value1), (1, value2), (1, value3),.....(1, value5000));
    

    오라클은> 수 1000 개 튜플하지만 단순 값을한다. 보기에 여기,

    https://community.oracle.com/message/3515498#3515498 과 https://community.oracle.com/thread/958612

    당신이 임시 테이블에서 필요한 값을 얻기 위해 IN 안에 하위 쿼리를 사용할 수있는 옵션이없는 경우이 물론이다.

  3. ==============================

    3.일부 해결 솔루션은 다음과 같습니다 :

    일부 해결 솔루션은 다음과 같습니다 :

    리터럴 적은 1000보다 그들을 사용하여 OR 절을 결합하여 여러 IN 절 분열 IN 절 :

    조건 "에서" ""절 조건 "IN"하나에서 여러 원래 분할 :

    Select id from x where id in (1, 2, ..., 1000,…,1500);
    

    에:

    Select id from x where id in (1, 2, ..., 999) OR id in (1000,...,1500);
    

    (1000)의 하나의 제한 항목의 집합에 적용 (X) IN ((1), (2), (3), ...). (X, 0) IN ((1,0), (2,0), (3,0), ...) : 세트 두 개 이상의 항목이 포함 된 경우에는 제한이 없습니다 :

    Select id from x where (x.id, 0) IN ((1, 0), (2, 0), (3, 0),.....(n, 0));
    
    Select id from x where id in (select id from <temporary-table>);
    
  4. ==============================

    4.또 하나 개의 방법 :

    또 하나 개의 방법 :

    CREATE OR REPLACE TYPE TYPE_TABLE_OF_VARCHAR2 AS TABLE OF VARCHAR(100);
    -- ...
    SELECT field1, field2, field3
      FROM table1
      WHERE name IN (
        SELECT * FROM table (SELECT CAST(? AS TYPE_TABLE_OF_VARCHAR2) FROM dual)
      );
    

    나는 그것의 최적를 고려하지 않지만, 그것을 작동합니다. 힌트 / * + CARDINALITY (...) * 오라클은 전달 된 배열의 카디널리티를 이해하지 않고 최적의 실행 계획을 추정 할 수 없기 때문에 / 매우 유용 할 것입니다.

    IN 술어에 대한 임시 테이블에 배치 삽입 및 하위 쿼리의 마지막을 사용하여 - 다른 대안으로.

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

    5.인 - 절의 내부 질의 내부를 사용하십시오 :

    인 - 절의 내부 질의 내부를 사용하십시오 :

    select col1, col2, col3... from table1
     where id in (select id from table2 where conditions...)
    
  6. ==============================

    6.또 다른 옵션이 있습니다 : 구문. 작전 예제를 사용하려면이 같을 것이다 :

    또 다른 옵션이 있습니다 : 구문. 작전 예제를 사용하려면이 같을 것이다 :

    with data as (
      select 'value1' name from dual
      union all
      select 'value2' name from dual
      union all
    ...
      select 'value10000+' name from dual)
    select field1, field2, field3 
    from table1 t1
    inner join data on t1.name = data.name;
    

    나는이 문제에 달렸다. 내 경우에는 내가 각 항목은 ITEM_ID과 CUSTOMER_ID했다 자바에서 데이터의 목록을했다. 나는 항목 각각의 고객에게 가입과 함께 DB에 두 개의 테이블이있다. 나는 함께 항목 ID로, 항목 또는 해당 항목에 대한 고객에게 모든 구독의 목록을 얻을 싶어요.

    나는 세 가지 변종을 시도했다 :

    옵션 1 : 자바에서 다중 선택

    기본적으로, 처음

    select item_id, token 
    from item_subs 
    where (item_id, 0) in ((:item_id_0, 0)...(:item_id_n, 0))
    

    그때

    select cus_id, token 
    from cus_subs 
    where (cus_id, 0) in ((:cus_id_0, 0)...(:cus_id_n, 0))
    

    그런 다음 ITEM_ID 그와 관련된 모든 항목에 대한 항목을 나는 키와 cus_id 및 값 항목의 목록을 자바로지도를 구축하고, 발견 된 각 고객의 가입에 대해 나는 (첫 번째 선택에서 반환 된 목록)를 추가합니다. 그것은 매우 지저분 코드입니다

    옵션 2 :와 구문

    는 SQL 등을 한 번에 모든 것을 얻을

    with data as (
      select :item_id_0 item_id, :cus_id_0 cus_id
      union all
      ...
      select :item_id_n item_id, :cus_id_n cus_id )
    select I.item_id item_id, I.token token
    from item_subs I
    inner join data D on I.item_id = D.item_id
    union all
    select D.item_id item_id, C.token token
    from cus_subs C
    inner join data D on C.cus_id = D.cus_id
    

    옵션 3 : 임시 테이블

    세 개의 필드로 전역 임시 테이블을 만듭니다 rownr (기본 키), ITEM_ID 및 cus_id. 모든 삽입 데이터가 2 번 다음에 매우 비슷한 선택을 실행할 수 있지만 데이터로 대신 임시 테이블에 연결

    공연

    이것은 완전히 과학적인 성능 분석하지 않습니다.

    YMMV.

    즉, 임시 테이블 옵션이 훨씬 느렸다 고 말했다. 이중 느린 마찬가지로. 나는 옵션 1 14~15초, 옵션 3 옵션 2의 15 ~ 16과 30를 얻고 있었다.

    나는 DB 서버와 동일한 네트워크에서 다시 시도하고 내가 기회를 얻을 때 변경 일 경우 확인합니다.

  7. ==============================

    7.이 문제를 해결하는 또 다른 방법도 있습니다. 두 테이블 표 1과 표 2를 가지고 있다고 할 수 있습니다. 기준 쿼리를 사용하여 표 2에 / 선물 언급하지 표 1의 모든 항목을 가져 오기 위해 필요합니다. 그래서 앞으로이 같은 갈 ...

    이 문제를 해결하는 또 다른 방법도 있습니다. 두 테이블 표 1과 표 2를 가지고 있다고 할 수 있습니다. 기준 쿼리를 사용하여 표 2에 / 선물 언급하지 표 1의 모든 항목을 가져 오기 위해 필요합니다. 그래서 앞으로이 같은 갈 ...

    List list=new ArrayList(); 
    Criteria cr=session.createCriteria(Table1.class);
    cr.add(Restrictions.sqlRestriction("this_.id not in (select t2.t1_id from Table2 t2 )"));
    .
    .
    

    . . . 그것은 하이버 네이트 프레임 워크에 의해 변환 된 SQL 1000 개 이상의 매개 변수를 포함하지 않고 SQL에서 직접 모든 하위 쿼리의 기능을 수행합니다. 그것은 나를 위해 일했습니다. 참고 : 귀하의 요구 사항에 따라 SQL 부분을 변경해야 할 수도 있습니다.

  8. ==============================

    8.나는이 오래된 질문 두꺼비를 참조 실감하지만 당신이 사용하는 C #을 주위에 코드를해야하는 경우 for 루프를 통해 목록을 분할 할 수 있습니다. 당신은 기본적으로 하위 목록 ()를 사용하여 자바와 같은 작업을 수행 할 수 있습니다;

    나는이 오래된 질문 두꺼비를 참조 실감하지만 당신이 사용하는 C #을 주위에 코드를해야하는 경우 for 루프를 통해 목록을 분할 할 수 있습니다. 당신은 기본적으로 하위 목록 ()를 사용하여 자바와 같은 작업을 수행 할 수 있습니다;

        List<Address> allAddresses = GetAllAddresses();
        List<Employee> employees = GetAllEmployees(); // count > 1000
    
        List<Address> addresses = new List<Address>();
    
        for (int i = 0; i < employees.Count; i += 1000)
        {
            int count = ((employees.Count - i) < 1000) ? (employees.Count - i) - 1 : 1000;
            var query = (from address in allAddresses
                         where employees.GetRange(i, count).Contains(address.EmployeeId)
                         && address.State == "UT"
                         select address).ToList();
    
            addresses.AddRange(query);
        }
    

    이 사람을 도움이되기를 바랍니다.

  9. ==============================

    9.운영 조합

    운영 조합

    select * from tableA where tableA.Field1 in (1,2,...999)
    union
    select * from tableA where tableA.Field1 in (1000,1001,...1999)
    union
    select * from tableA where tableA.Field1 in (2000,2001,...2999)
    
  10. ==============================

    10.다른 솔루션은 오래된 프레임 워크를 사용하여 구현하기가 어려웠다 나를 위해 일한 배열의 분리를하고이 해결합니다.

    다른 솔루션은 오래된 프레임 워크를 사용하여 구현하기가 어려웠다 나를 위해 일한 배열의 분리를하고이 해결합니다.

    select * from tableA where id = 1 or id = 2 or id = 3 ...
    

    가능하지만 더 나은 PERFO, 나는, 노동 조합과 니콜라이 Nechai의 솔루션을 사용합니다.

  11. ==============================

    11.

        **Divide a list to lists of n size**
    
        import java.util.AbstractList;
        import java.util.ArrayList;
        import java.util.List;
    
        public final class PartitionUtil<T> extends AbstractList<List<T>> {
    
            private final List<T> list;
            private final int chunkSize;
    
            private PartitionUtil(List<T> list, int chunkSize) {
                this.list = new ArrayList<>(list);
                this.chunkSize = chunkSize;
            }
    
            public static <T> PartitionUtil<T> ofSize(List<T> list, int chunkSize) {
                return new PartitionUtil<>(list, chunkSize);
            }
    
            @Override
            public List<T> get(int index) {
                int start = index * chunkSize;
                int end = Math.min(start + chunkSize, list.size());
    
                if (start > end) {
                    throw new IndexOutOfBoundsException("Index " + index + " is out of the list range <0," + (size() - 1) + ">");
                }
    
                return new ArrayList<>(list.subList(start, end));
            }
    
            @Override
            public int size() {
                return (int) Math.ceil((double) list.size() / (double) chunkSize);
            }
        }
    
    
    
    
    
    Function call : 
                  List<List<String>> containerNumChunks = PartitionUtil.ofSize(list, 999)
    

    자세한 내용은 : https://e.printstacktrace.blog/divide-a-list-to-lists-of-n-size-in-Java-8/

  12. from https://stackoverflow.com/questions/17842453/is-there-a-workaround-for-ora-01795-maximum-number-of-expressions-in-a-list-is by cc-by-sa and MIT license