ora-01795有解决方法吗:一个列表中的表达式的最大数目是1000个错误?

ufj5ltwl  于 2021-07-29  发布在  Java
关注(0)|答案(11)|浏览(554)

有解决方法吗 'ORA-01795: maximum number of expressions in a list is 1000 error' 我有一个查询,它根据一个字段的值选择字段。我使用in子句,有10000+个值
例子:

  1. select field1, field2, field3
  2. from table1
  3. where name in
  4. (
  5. 'value1',
  6. 'value2',
  7. ...
  8. 'value10000+'
  9. );

每次执行查询时,我都会得到 ORA-01795: maximum number of expressions in a list is 1000 error . 我试图在toad中执行查询,没有区别,相同的错误。如何修改查询以使其工作?
提前谢谢

iaqfqrcu

iaqfqrcu1#

只要使用多个in子句就可以解决这个问题:

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

lsmepo6l2#

一些变通解决方案包括:

1. 在子句中拆分

将in子句拆分为多个in子句,其中文字量小于1000,并使用or子句组合它们:
将原来的“where”子句从一个“in”条件拆分为几个“in”条件:

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

收件人:

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

2. 使用元组

1000的限制适用于单个项目的集合:(x)in((1),(2),(3),…)。如果集合包含两个或多个项目,则没有限制:(x,0)in((1,0),(2,0),(3,0),…):

  1. Select id from x where (x.id, 0) IN ((1, 0), (2, 0), (3, 0),.....(n, 0));

3. 使用临时表

  1. Select id from x where id in (select id from <temporary-table>);
展开查看全部
6uxekuva

6uxekuva3#

我最近碰到了这个问题,想出了一个厚颜无耻的方法,不用把附加条款串在一起
你可以利用元组

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

oracle允许大于1000个元组,但不允许简单值。更多关于这个,
https://community.oracle.com/message/3515498#3515498

https://community.oracle.com/thread/958612
当然,如果您不能选择在中使用子查询从temp表中获取所需的值,那么就需要这样做。

uinbv5nw

uinbv5nw4#

还有一种方法:

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

我不认为这是最佳的,但它的工作。暗示 /*+ CARDINALITY(...) */ 这将非常有用,因为oracle不了解所传递数组的基数,也无法估计最佳执行计划。
另一种方法是批量插入临时表,并使用 IN 谓语。

s3fp2yjn

s3fp2yjn5#

请在 in -条款:

  1. select col1, col2, col3... from table1
  2. where id in (select id from table2 where conditions...)
tkqqtvp1

tkqqtvp16#

还有另一种选择: with 语法。要使用ops示例,这将如下所示:

  1. with data as (
  2. select 'value1' name from dual
  3. union all
  4. select 'value2' name from dual
  5. union all
  6. ...
  7. select 'value10000+' name from dual)
  8. select field1, field2, field3
  9. from table1 t1
  10. inner join data on t1.name = data.name;

我遇到了这个问题。在我的例子中,java中有一个数据列表,其中每个项都有一个item\ id和一个customer\ id。我想得到一个项目或该项目的客户的所有订阅的列表,以及项目id。
我尝试了三种变体:
java中的多个选择(使用元组绕过限制)
使用语法
临时工作台
选项1:从java中选择多个
基本上,我先

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

然后

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

然后,我在java中构建了一个以cus\u id为键、以项列表为值的Map,并为每个找到的客户订阅添加(到从第一个select返回的列表中)一个条目,用于所有具有该项id的相关项
选项2:使用语法
使用类似sql的

  1. with data as (
  2. select :item_id_0 item_id, :cus_id_0 cus_id
  3. union all
  4. ...
  5. select :item_id_n item_id, :cus_id_n cus_id )
  6. select I.item_id item_id, I.token token
  7. from item_subs I
  8. inner join data D on I.item_id = D.item_id
  9. union all
  10. select D.item_id item_id, C.token token
  11. from cus_subs C
  12. inner join data D on C.cus_id = D.cus_id

方案3:临时桌
创建一个全局临时表,其中包含三个字段:rownr(主键)、item\u id和cus\u id。在其中插入所有数据,然后运行与选项2非常相似的select,但在临时表中链接,而不是 with data 演出
这不是一个完全科学的性能分析。
我运行的是一个开发数据库,在我的数据集中有略多于1000行的数据,我想为其查找订阅。
我只试过一个数据集。
我和我的数据库服务器不在同一个物理位置。虽然距离不远,但我注意到如果我在家尝试使用vpn,速度会慢得多,即使距离是一样的(问题不在我家的互联网上)。
我正在测试完整的调用,所以我的api调用另一个(也在dev的同一个示例中运行)也连接到db以获取初始数据集。但这三种情况都是一样的。
基督教青年会。
也就是说,临时表选项要慢得多。就像在双人床上一样慢。我得到14-15秒的选择1,15-16的选择2和30的选择3。
我会在db服务器的同一个网络上再试一次,如果有机会的话,我会检查是否会改变。

展开查看全部
nhjlsmyf

nhjlsmyf7#

还有另一种方法来解决这个问题。假设您有两张表table1和table2。并且需要使用条件查询获取表2中未引用/存在的表1的所有条目。就这样继续吧。。。

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

. . . 它将直接在sql中执行所有子查询函数,而不包括hibernate框架转换的sql中的1000个或更多参数。它对我有用。注意:您可能需要根据需要更改sql部分。

l7wslrjt

l7wslrjt8#

我意识到这是一个老问题,指的是toad,但是如果你需要用c来处理这个问题,你可以通过for循环来分解这个列表。基本上可以使用sublist()对java执行相同的操作;

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

希望这对别人有帮助。

展开查看全部
vhmi4jdf

vhmi4jdf9#

操作员联合

  1. select * from tableA where tableA.Field1 in (1,2,...999)
  2. union
  3. select * from tableA where tableA.Field1 in (1000,1001,...1999)
  4. union
  5. select * from tableA where tableA.Field1 in (2000,2001,...2999)
ivqmmu1c

ivqmmu1c10#

  1. **Divide a list to lists of n size**
  2. import java.util.AbstractList;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. public final class PartitionUtil<T> extends AbstractList<List<T>> {
  6. private final List<T> list;
  7. private final int chunkSize;
  8. private PartitionUtil(List<T> list, int chunkSize) {
  9. this.list = new ArrayList<>(list);
  10. this.chunkSize = chunkSize;
  11. }
  12. public static <T> PartitionUtil<T> ofSize(List<T> list, int chunkSize) {
  13. return new PartitionUtil<>(list, chunkSize);
  14. }
  15. @Override
  16. public List<T> get(int index) {
  17. int start = index * chunkSize;
  18. int end = Math.min(start + chunkSize, list.size());
  19. if (start > end) {
  20. throw new IndexOutOfBoundsException("Index " + index + " is out of the list range <0," + (size() - 1) + ">");
  21. }
  22. return new ArrayList<>(list.subList(start, end));
  23. }
  24. @Override
  25. public int size() {
  26. return (int) Math.ceil((double) list.size() / (double) chunkSize);
  27. }
  28. }
  29. Function call :
  30. List<List<String>> containerNumChunks = PartitionUtil.ofSize(list, 999)

更多详细信息:https://e.printstacktrace.blog/divide-a-list-to-lists-of-n-size-in-java-8/

展开查看全部
zsohkypk

zsohkypk11#

还有一个解决方法是对数组进行析取,这对我来说很有用,因为其他解决方案很难使用一些旧的框架实现。

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

但是为了更好的表现,如果可能的话,我会用尼科莱·内查伊的解决方案。

相关问题