oracle sql in more than 1000 parameters report error (ORA-01795: the maximum number of expressions in the list is 1000) one of the solutions

        In oracle database, when SQL uses in, if the energy number of in exceeds 1000, it will report "ORA- 01795 : maximum number of expressions in a list is 1000 / ORA - 01795 : maximum number of expressions in a list is 1000" This is one of the pits that everyone often stepped on in production!

       In the test environment, because of the small amount of data, the test cases are not covered. In some scenes, everyone will feel that under normal circumstances it will definitely not exceed 1000 (think Murphy's law) during the evaluation time, and the dark thunder has often been planted at this time!

    There are many solutions to ORA-01795 on the Internet, such as using in() or in(), creating a temporary table join, using union, etc. I also provide a solution here. There is no standard for the solution. As for the choice, it depends on your own. Preferences and application scenarios.

 

官方说:A comma-delimited list of expressions can contain no more than 1000 expressions. A comma-delimited list of sets of expressions can contain any number of sets, but each set can contain no more than 1000 expressions.

        The oracle tuple (A comma-delimited list of sets of expressions) is used here, which is a tuple, the syntax is as follows:

SELECT * FROM TABLE_NAME WHERE (1, COLUMN_NAME) IN 
((1, VALUE_1), 
(1, VALUE_2), 
...
...
...
...
(1, VALUE_1000),
(1, VALUE_1001));

For example, if we want to query user information by user id from the user table, we can write:

select * from t_user u where (1, u.id) in ((1, 'id001'),(1,'id002'),(1,'XXX'))

The above statement is actually equivalent to: select * from t_user u where (1=1 and u.id='id001') or (1=1 and u.id='id002') or (1=1 and u.id= 'XXX')

Most of your projects will use ORM frameworks such as MyBatis. We can use MyBatis foreach. It turns out that this is written:

 WHERE u.id IN(
        <foreach collection="list" item="item" index="index" separator=",">
            #{item}
        </foreach>
        )

Now make a slight modification:

 WHERE (1, u.id) IN(
        <foreach collection="list" item="item" index="index" separator=",">
            (1, #{item})
        </foreach>
        )

Personal advice: This is not the best way. If the amount of data is large, it is recommended that you do paging. If the amount of data is large, database paging is recommended. I also have an article on memory paging. If you need it, everyone You can refer to: Use java8 stream api to realize List collection paging acquisition tool

In addition, here is also to remind our testers that in some batch processing of functional tests, it is best to consider the case of large amounts of data processing when designing the use case!

Reference document: https://docs.oracle.com/database/121/SQLRF/expressions016.htm#SQLRF52099

                  http://dbaparadise.com/2016/07/limitations-of-the-in-clause-in-oracle-ora-01795/#3

If you run the query in the application, and you need to run it often, then definitely Tom Kyte’s solution is the best. Basically he recommends the following:

Suggest you create a global temporary table, array insert your “in list” into this table and use
select …. and ( t.e in ( select * from global_temp_table );”

Guess you like

Origin blog.csdn.net/kevin_mails/article/details/89508268