SQL语句太长了,需要通过dbms_sql.varchar2s这个数组类型来进行存储。然后才能执行。
declare
l_stmtdbms_sql.varchar2s;
l_cursorintegerdefaultdbms_sql.open_cursor;
l_rowsnumberdefault0;
l_lengthnumber:=0;
begin
l_stmt(1):='select1c1';
foriin2..15000loop
l_stmt(i):=',1c'||i;
endloop;
l_stmt(15000):='fromdual';
foriinl_stmt.first..l_stmt.last
loop
l_length:=l_length+length(l_stmt(i));
endloop;
dbms_output.put_line('length='||l_length);
dbms_sql.parse(c=>l_cursor,
statement=>l_stmt,
lb=>l_stmt.first,
ub=>l_stmt.last,
lfflg=>TRUE,
language_flag=>dbms_sql.native);
l_rows:=dbms_sql.execute(l_cursor);
dbms_sql.close_cursor(l_cursor);
end;
/
以下参考:stcore/html/2006/0307/114096.html
最近遇见一个ORA-01795:maximumnumberofexpressionsinalistis1000错误,才知道In-list有1000个元素的限制;可以使用arraybind或者temporarytable解决,而且还能绑定变量。[LimitandconversionverylongINlist:WHERExIN(,,,...)]
再想到SQL的长度是否在SQLPLUS里面还有其他的限制?
LogicalDatabaseLimits
SQLStatementLength
Maximumlengthofstatements
64Kmaximum;particulartoolsmayimposelowerlimits
9i的文档写的最大64K,其实不正确。
在10g的文档中作了修改LogicalDatabaseLimits
ThelimitonhowlongaSQLstatementcanbedependsonmanyfactors,includingdatabaseconfiguration,diskspace,andmemory
仔细想想,我们数据库中package几十K有很多,当初都是用sqlplus执行创建的;sqlpplus对日常执行的SQL因该不会有长度限制。
先测试一下使用DBMS_SQL执行很长的SQL语句。
SQL>declare
2l_stmtdbms_sql.varchar2s;
l_cursorintegerdefaultdbms_sql.open_cursor;
l_rowsnumberdefault0;
345l_lengthnumber:=0;
6begin
7l_stmt(1):='select1c1';
8foriin2..15000
9loop
10l_stmt(i):=',1c'||i;
11endloop;
12l_stmt(15000):='fromdual';
13foriinl_stmt.first..l_stmt.last
14loop
15l_length:=l_length+length(l_stmt(i));
16endloop;
17dbms_output.put_line('length='||l_length);
18dbms_sql.parse(c=>l_cursor,
19statement=>l_stmt,
20lb=>l_stmt.first,
21ub=>l_stmt.last,
22lfflg=>TRUE,
23language_flag=>dbms_sql.native);
25l_rows:=dbms_sql.execute(l_cursor);
26dbms_sql.close_cursor(l_cursor);
27end;
28/
length=138898
PL/SQLproceduresuccessfullycompleted.
通过dbms_sql.varchar2s数组,可以执行很长的SQL。
再将如上pl/sql产生的SQL使用dbms_output输出longSQL.sql.
SQL>hostls-llongSQL.sql
-rw-r--r--1oracledba1215082Dec405:19longSQL.sql
SQL>hostheadlongSQL.sql
select1c1
,1c2
...........................
SQL>hosttaillongSQL.sql
................
,1c14999
,1c15000
fromdual;
这个1M的SQL在sqlplus里完全可以执行。看来,oracle完全支持很长的SQL语句;但该sql会占用很多sharepool空间,因此不提倡经常执行。
SQL>selectsql_text,SHARABLE_MEM,PERSISTENT_MEM,RUNTIME_MEMfromv$sqlwheresql_textlike'%,1c2%';
SQL_TEXT
--------------------------------------------------------------------------
SHARABLE_MEMPERSISTENT_MEMRUNTIME_MEM
-------------------------------------
select1c1,1c2,1c3,1c4,1c5,1c6,1c7,1c8,1c9,1c10,1
c11,1c12,1c13,1c14,1c15,1c16,1c17,1c18,1c19,1,1.............................................................................................
1978774780448241252