我有一个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
答案 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”语句。