解决SQL in 1000条限制

       处理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(); // 获得一共有多少类



你可能感兴趣的:(解决SQL in 1000条限制)