java.sql.SQLException:ORA-24335:不能支持1000多列

时间:2014-12-17 19:39:39

标签: java oracle oracle11g

我有一个java程序,它使用一个名为pilotID的唯一ID将商店编号列表插入到Oracle数据库中,语法如下:

pilotDAO.insertPilotStores(pilotID, storeList);

storeList是存储商店号码的List<String>pilotID是101之类的整数。

但是,当storelist超过999个商店时,我在Oracle中遇到了数据库异常:

Caused by:
    java.sql.SQLException: ORA-24335: cannot support more than 1000 columns

使用的插入查询是

INSERT ALL
  INTO eportal.pilot_store (pilot_id, store_nbr, last_updt_dt_tme) VALUES (96, 100, SYSDATE)
  INTO eportal.pilot_store (pilot_id, store_nbr, last_updt_dt_tme) VALUES (96, 101, SYSDATE)
  INTO eportal.pilot_store (pilot_id, store_nbr, last_updt_dt_tme) VALUES (96, 102, SYSDATE)
SELECT * FROM dual;

我真的被困在这里了。欢迎任何建议。

提前致谢
POOJA

5 个答案:

答案 0 :(得分:3)

问题在于INSERT ALL。此功能是为多个表插入(MTI)设计的,它不是为在一个表中插入多行而设计的。您可以重新编写查询以使用单个插入语句。或者你可以这样写:

INSERT INTO eportal.pilot_store (pilot_id, store_nbr, last_updt_dt_tme)
select 96, 100, SYSDATE from dual UNION ALL
select 96, 101, SYSDATE from dual UNION ALL
select 96, 102, SYSDATE from dual UNION ALL
....;

答案 1 :(得分:2)

您正在达到数据库中的最大列数。 您很可能需要将其更改为准备好的语句并将其多次调用。每个&#34;进入....&#34;被oracle认为是一栏我想冒险,如果你有

INSERT ALL
  INTO eportal.pilot_store (....)
  999 more rows
SELECT * FROM dual;

然后确实它不起作用。

而是试试这个(adapted from this question

public void insertStores(int pilotId, List<Store> stores) throws SQLException { 
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    try {
        connection = database.getConnection();
        connection.setAutoCommit(false);
        preparedStatement = connection.prepareStatement("INSERT INTO eportal.pilot_store (pilot_id, store_nbr, last_updt_dt_time) values (?, ?, SYSDATE)");

        // ofcourse adapt to use your own list of store id's etc.
        for (Store store : stores) {
            preparedStatement.setInt(1, pilotId);
            preparedStatement.setInt(2, store.getNumber());
            preparedStatement.addBatch();
        }
        preparedStatement.executeBatch();
        connection.commit();
    } catch (SQLException e) {
        connection.rollback();
        throw e;
    } finally {
        close(preparedStatement);
        close(connection);
    }
}

答案 2 :(得分:2)

正如您所注意到INSERT ALL对大量行的效果不佳您可以使用UNION ALL而不是

INSERT INTO
  eportal.pilot_store (pilot_id, store_nbr, last_updt_dt_tme) 
select 96, 100, SYSDATE from dual
union all
  select 96, 101, SYSDATE from dual
union all 
   select 96, 102, SYSDATE from dual

你可以像这样使用StringBuilder重写你的查询

StringBuilder sb = new StringBuilder("INSERT INTO eportal.pilot_store (pilot_id, store_nbr, last_updt_dt_tme) ");
String unionAll = " union all ";
for(int i = 100; i < 103; i++) {

    sb.append("select 96,").append(i).append(", SYSDATE from dual").append(unionAll);
}
sb.delete(sb.length() - unionAll.length(), sb.length());
sb.append(";");

答案 3 :(得分:1)

您可以使用批量插入而不是全部插入

在Java中,它将是这样的 Oracle JDBC batching

优点 - 简单的插入查询,良好的性能。

在查询中使用文字不是Oracle的正确选择(特别是对于经常运行的查询),因为oracle每次都会解析查询, 并且会在共享池中造成混乱。

答案 4 :(得分:0)

它以这种方式对我有用:

INSERT INTO eportal.pilot_store (pilot_id, store_nbr, last_updt_dt_tme)
        SELECT 96, 100, SYSDATE FROM dual UNION ALL
        SELECT 96, 101, SYSDATE FROM dual UNION ALL
        SELECT 96, 102, SYSDATE FROM dual;

注意最后一行不应有“UNION ALL”语句。