[20180926]神奇的规避ORA-01795方法.txt
[20180926]神奇的规避ORA-01795方法.txt
--//大家知道in里面的值限制1000个值,如果超出报ORA-01795错误.
D:\> ooerr 01795
01795, 00000, "maximum number of expressions in a list is 1000"
D:\> oerr ora 01795
01795, 00000, "maximum number of expressions in a list is 1000"
// *Cause: Number of expressions in the query exceeded than 1000.
// Note that unused column/expressions are also counted
// Maximum number of expressions that are allowed are 1000.
// *Action: Reduce the number of expressions in the list and resubmit.
--//别人的awr报表我仔细查看,发现对方规避ora-01795的方法,使用集合的概念,仔细一想难道集合就没有1000个的限制吗?
--//我仔细看对方程序是写死的,2000个集合,明显这样是没有问题的.
--//有时候还是给佩服开发的想象力,我还是做一些例子说明问题.
1.环境:
SCOTT@test01p> @ ver1
PORT_STRING VERSION BANNER CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0 12.1.0.1.0 Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0
SCOTT@test01p> create table t as select * from all_objects;
Table created.
SCOTT@test01p> create unique index i_t_object_id on t(object_id);
Index created.
--//分析表略.
2.测试1:
variable b1 number;
variable b2 number;
exec :b1 :=42;
exec :b2 :=47;
SCOTT@test01p> select * from t where (1,object_id) in ((1,:b1),(1,:b2));
OWNER OBJECT_NAME SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_TIME TIMESTAMP
----- ----------- -------------- --------- -------------- -------------------- ------------------- ------------------- -------------------
SYS I_ICOL1 42 42 INDEX 2013-06-28 09:03:29 2013-06-28 09:03:29 2013-06-28:09:03:29
SYS I_USER2 47 47 INDEX 2013-06-28 09:03:29 2013-06-28 09:03:29 2013-06-28:09:03:29
--//OK没有问题,里面仅仅包含2个集合,如果更多呢?
3.测试2:
select 'variable b'||to_char(level)||' number;' txt from dual connect by level<=1001
union all
select 'exec :b'||to_char(level)||' :='|| to_char(level) txt from dual connect by level<=1001
union all
select 'select * from t where (1,object_id) in (' txt from dual
union all
select '(1,:b'||to_char(level)||'),' txt from dual connect by level<=1000
union all
select '(1,:b'||to_char(1001)||'));' txt from dual ;
--//将输出保存1个脚本,适当编辑执行.ok,没有任何问题.执行计划如下:
Plan hash value: 3525592940
----------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 196 (100)| | 891 |00:00:00.01 | 40 |
| 1 | INLIST ITERATOR | | 1 | | | | | 891 |00:00:00.01 | 40 |
| 2 | TABLE ACCESS BY INDEX ROWID| T | 1001 | 1001 | 112K| 196 (0)| 00:00:01 | 891 |00:00:00.01 | 40 |
|* 3 | INDEX UNIQUE SCAN | I_T_OBJECT_ID | 1001 | 1001 | | 178 (0)| 00:00:01 | 891 |00:00:00.01 | 22 |
----------------------------------------------------------------------------------------------------------------------------------------
--//1001个集合没有任何问题.
--//修改b200-b999变量等于0,测试看看:
Plan hash value: 3525592940
----------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 196 (100)| | 193 |00:00:00.01 | 16 |
| 1 | INLIST ITERATOR | | 1 | | | | | 193 |00:00:00.01 | 16 |
| 2 | TABLE ACCESS BY INDEX ROWID| T | 203 | 1001 | 112K| 196 (0)| 00:00:01 | 193 |00:00:00.01 | 16 |
|* 3 | INDEX UNIQUE SCAN | I_T_OBJECT_ID | 203 | 1001 | | 178 (0)| 00:00:01 | 193 |00:00:00.01 | 12 |
----------------------------------------------------------------------------------------------------------------------------------------
--//可以发现starts=203,重复值不会扫描的.
4.我的估计:
--//对方2000个集合写死的,我估计可能是一个数组,初始赋值0(或者查询不到的值),然后赋值.
--//通过这样的方式实现绑定变量.
--//我个人还是趋向这样的方式使用临时表更加合理简单一些.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库