您的位置:首页 > 数据库

解决SQL in 1000条限制

2015-06-16 00:00 363 查看
处理oracle sql 语句in子句中(where id in (1, 2, ..., 1000, 1001)),如果子句中超过1000项就会报错。这主要是oracle考虑性能问题做的限制。如果要解决次问题,可以用 where id (1, 2, ..., 1000) or id (1001, ...)。

这里探讨得是另一种实现方式,将传入的项在数据库做类似于虚拟表的一列数据,然后做关联查询。

数据库创建函数和类型:

CREATE OR REPLACE TYPE mytable AS TABLE OF varchar2(5000);

CREATE OR REPLACE FUNCTION STR_SPLIT (src clob, delimiter varchar2)

RETURN mytable IS

psrc clob;

a mytable := mytable();

i NUMBER := 1;

j NUMBER := 1;

BEGIN

psrc := RTrim(LTrim(src, delimiter), delimiter);

LOOP

i := InStr(psrc, delimiter, j);

IF i>0 THEN

a.extend;

a(a.Count) := Trim(SubStr(psrc, j, i-j));

j := i+1;

END IF;

EXIT WHEN i=0;

END LOOP;

IF j <= Length(psrc) THEN

a.extend;

a(a.Count) := Trim(SubStr(psrc, j, Length(psrc)+1-j));

END IF;

RETURN a;

END;

函数STR_SPLIT 主要是将传入的参数src项,根据delimiter 分隔符分割成表的一列数据。src类型为clob主要考虑传入字符串超过4000的限制。

java调用:

service层:

boolean pand = true; //字符串 元素个数是否小于1000

if(StringUtil.isNotBlank(userCode)) {

if (userCode.split(",").length > 1000)

pand = false;

if (pand) {

where += " and u.usercode not in ("+userCode+")";

} else { //传参

where += " and u.usercode not exists (select distinct column_value from table(CAST(SEND_SPLIT(?, ',') as mytable)) where u.usercode=column_value)";

}

}

//如果大于1000 非包含用not exists比not in效率高。

// in/not in (select distinct column_value from table(CAST(SEND_SPLIT(?, ',') as mytable)

// exists/ not exists (select distinct column_value from table(CAST(SEND_SPLIT(?, ',') as mytable) 主表.字段=column_value))

where += " order by u.username";

sql.append(where);

if (pand)

return mapDataDao.queryListBySQL(sql.toString());

else

return mapDataDao.queryListBySQLParam(sql.toString(), new Object[] {userCode});

dao层:

Connection conn = getConnection(jndiName, session);

ResultSet rs = null;

//OraclePreparedStatement statement = null;

PreparedStatement statement = null;

OracleConnection connection = null;

List list = new JSONArray();

PaginationSupport ps = null;

try {

//NewProxyConnection转换为OracleConnection

C3P0NativeJdbcExtractor cp30NativeJdbcExtractor = new C3P0NativeJdbcExtractor();

connection = (OracleConnection) cp30NativeJdbcExtractor.getNativeConnection(conn);

//statement = (OraclePreparedStatement)connection.prepareStatement(sql);

statement = conn.prepareStatement(sql);

if (param[0] != null && param[0].toString().length() > 0) {

//statement.setStringForClob(1, param[0].toString());

CLOB clob = CLOB.createTemporary(connection, false, oracle.sql.CLOB.DURATION_SESSION);

clob.open(CLOB.DURATION_SESSION);

Writer writer = clob.getCharacterOutputStream();

writer.write(param[0].toString().toCharArray());

writer.flush();

writer.close();

statement.setClob(1, clob);

}

rs = statement.executeQuery();

ResultSetMetaData rsmd = rs.getMetaData(); // 获得结果集的模型(列的相关信息)

int columnCount = rsmd.getColumnCount(); // 获得一共有多少类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: