【发布时间】:2015-12-02 02:35:33
【问题描述】:
在我们的项目中,我创建了一些全局临时表,如下所示:
CREATE GLOBAL TEMPORARY TABLE v2dtemp (
id NUMBER,
GOOD_TYPE_GROUP VARCHAR2(250 BYTE),
GOOD_CODE VARCHAR2(50 BYTE),
GOOD_TITLE VARCHAR2(250 BYTE)
)
ON COMMIT PRESERVE ROWS;
但是当我想删除这个表时问题就来了。 Oracle 不会让我删除表,它说:
ORA-14452: attempt to create, alter or drop an index on temporary table already in use
我必须在某些过程中使用此表,但它可能会根据其他报告而更改。所以我应该总是删除表格,然后我应该用我需要的字段重新创建它。
出于某些业务原因,我必须使用它,因此我无法使用表格或其他东西。我可以只使用临时表。 我尝试提交删除行,但是当我调用我的过程以使用此表中的数据时,表中没有更多行并且它们已被删除。
任何帮助将不胜感激, 提前致谢
/// 编辑
public void saveJSONBatchOpenJobs(final JSONArray array, MtdReport report) {
dropAndCreateTable();
String sql = "INSERT INTO v2d_temp " +
"(ID, KARPARDAZ, GOOD_TYPE_GROUP, GOOD_CODE, GOOD_TITLE, COUNT, "
+ "FACTOR_COUNT, GHABZ_COUNT, DEAL_NO, DEAL_DATE, REQUEST_NO, REQUEST_DATE, "
+ "REQUEST_CLIENT, STATUS, TYPE, MTDREPORT_ID, GEN_SECURITY_DATA_ID) " +
"VALUES (MTD_KARPARDAZ_OPEN_JOBS_SEQ.nextval,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
JSONArray values = array.getJSONArray(i);
if(!values.get(0).equals("null"))
ps.setString(1, values.get(0).toString());
else
ps.setNull(1, Types.VARCHAR);
if(!values.get(1).equals("null"))
ps.setString(2, values.get(1).toString());
else
ps.setNull(2, Types.VARCHAR);
if(!values.get(2).equals("null"))
ps.setString(3, values.get(2).toString());
else
ps.setNull(3, Types.VARCHAR);
if(!values.get(3).equals("null"))
ps.setString(4, values.get(3).toString());
else
ps.setNull(4, Types.VARCHAR);
if(!values.get(4).equals("null"))
ps.setBigDecimal(5, new BigDecimal(values.get(4).toString()));
else
ps.setNull(5, Types.NUMERIC);
if(!values.get(5).equals("null"))
ps.setBigDecimal(6, new BigDecimal(values.get(5).toString()));
else
ps.setNull(6, Types.NUMERIC);
if(!values.get(6).equals("null"))
ps.setBigDecimal(7, new BigDecimal(values.get(6).toString()));
else
ps.setNull(7, Types.NUMERIC);
if(!values.get(7).equals("null"))
ps.setString(8, values.get(7).toString());
else
ps.setNull(8, Types.VARCHAR);
if(!values.get(8).equals("null"))
ps.setDate(9, new Date(new Timestamp(values.getLong(8)).getDateTime()));
else
ps.setNull(9, Types.DATE);
if(!values.get(9).equals("null"))
ps.setString(10, values.get(9).toString());
else
ps.setNull(10, Types.VARCHAR);
if(!values.get(10).equals("null"))
ps.setDate(11, new Date(new Timestamp(values.getLong(8)).getDateTime()));
else
ps.setNull(11, Types.DATE);
if(!values.get(11).equals("null"))
ps.setString(12, values.get(11).toString());
else
ps.setNull(12, Types.VARCHAR);
if(!values.get(12).equals("null"))
ps.setString(13, values.get(12).toString());
else
ps.setNull(13, Types.VARCHAR);
if(!values.get(13).equals("null"))
ps.setString(14, values.get(13).toString());
else
ps.setNull(14, Types.VARCHAR);
if(!values.get(14).equals("null"))
ps.setLong(15, new Long(values.get(14).toString()));
else
ps.setNull(15, Types.NUMERIC);
if(!values.get(15).equals("null"))
ps.setLong(16, new Long(values.get(15).toString()));
else
ps.setNull(16, Types.NUMERIC);
}
@Override
public int getBatchSize() {
return array.size();
}
});
String bulkInsert = "declare "
+ "type array is table of d2v_temp%rowtype;"
+ "t1 array;"
+ "begin "
+ "select * bulk collect into t1 from d2v_temp;"
+ "forall i in t1.first..t1.last "
+ "insert into vertical_design values t1(i);"
+ "end;";
executeSQL(bulkInsert);
}
private void dropAndCreateTable() {
String dropSql = "declare c int;"
+ "begin "
+ "select count(*) into c from user_tables where table_name = upper('v2d_temp');"
+ "if c = 1 then "
+ "truncate table v2d_temp"
+ "drop table v2d_temp;"
+ " end if;"
+ "end;";
executeSQL(dropSql);
String createSql = "CREATE GLOBAL TEMPORARY TABLE v2d_temp (\n"
+ "DEAL_ID NUMBER,\n"
+ "id NUMBER,\n"
+ "karpardaz VARCHAR2(350),\n"
+ "GOOD_TYPE_GROUP VARCHAR2(250 BYTE),\n"
+ "GOOD_CODE VARCHAR2(50 BYTE),\n"
+ "GOOD_TITLE VARCHAR2(250 BYTE),\n"
+ "COUNT NUMBER,\n"
+ "FACTOR_COUNT NUMBER,\n"
+ "GHABZ_COUNT NUMBER,\n"
+ "DEAL_NO VARCHAR2(50 BYTE),\n"
+ "DEAL_DATE DATE,\n"
+ "REQUEST_NO VARCHAR2(50 BYTE),\n"
+ "REQUEST_DATE DATE,\n"
+ "REQUEST_CLIENT VARCHAR2(250 BYTE),\n"
+ "STATUS VARCHAR2(250 BYTE),\n"
+ "TYPE VARCHAR2(250 BYTE),\n"
+ "GEN_SECURITY_DATA_ID NUMBER(10),\n"
+ "MTDREPORT_ID NUMBER\n"
+ ")\n"
+ "ON COMMIT PRESERVE ROWS";
executeSQL(createSql);
}
private void executeSQL(String sql) {
Connection con = null;
try {
con = getConnection();
Statement st = con.createStatement();
st.execute(sql);
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
【问题讨论】:
-
全局临时表不应该以这种方式使用。它们应该被定义为模式的一部分,并且它们的结构不应随着每次使用/程序执行而改变。如果您有多个使用临时存储的程序,请为您需要的每个数据结构定义全局临时表。您还可以在查询中使用子查询分解,它可以在免费中创建临时表或使用 /*+ materialize */ 提示强制它(有一些限制)。
-
我的老板坚持让我使用这种方式,临时表等,所以我别无选择。这是我在寻找使用临时表和使用其他部分中的数据的任何其他方式的第二天,您能指导我使用其他方式吗?
-
那你老板不懂Oracle是怎么工作的。
-
寻找另一份工作。你不会在那里学到任何有价值的东西。
-
也许你是对的,但现在,在这个时刻我必须找到解决这个问题的方法,他坚持认为有办法做到这一点,当我解释更多细节时是没有办法通过临时表做到这一点的,我让他更生气,他在想我现在对 oracle 一无所知!我在第一个答案的 cmets 中解释了更多细节,如果您对如何强制 oracle 删除一些临时表而不考虑其他会话数据有任何想法,如果您与我分享,我将不胜感激。
标签: oracle plsql ddl temp-tables