最近写了特别多的数据库同步接口,需要在java程序中拼接大段的sql,然后再提交执行,出现了很多次ORA-00923错误,都有点见怪不怪了。
比如下面这段代码,在执行 db.execute(insertSql) 时肯定会报这个错误的。
@Override
public int doInsert(DB db,InterfaceLogBean logBean) {
StringBuilder insertBuilder = new StringBuilder();
insertBuilder.append("INSERT INTO ");
insertBuilder.append("MTL_ONHAND_QUANTITIES_DETAIL ");
insertBuilder.append("(INVENTORY_ITEM_ID,ITEM_CODE,ORGANIZATION_ID,DATE_RECEIVED,LAST_UPDATE_DATE,LAST_UPDATED_BY,CREATION_DATE,CREATED_BY,");
insertBuilder.append("PRIMARY_TRANSACTION_QUANTITY,SUBINVENTORY_CODE,LOT_NUMBER,ONHAND_QUANTITIES_ID,ORGANIZATION_TYPE,");
insertBuilder.append(" OWNING_ORGANIZATION_ID,TRANSACTION_UOM_CODE,TRANSACTION_QUANTITY,IS_CONSIGNED)");
insertBuilder.append("SELECT INVENTORY_ITEM_ID,ITEM_CODE,84,DATE_RECEIVED,LAST_UPDATE_DATE,LAST_UPDATED_BY,CREATION_DATE,CREATED_BY, ");
insertBuilder.append("PRIMARY_TRANSACTION_QUANTITY,SUBINVENTORY_CODE,LOT_NUMBER,ONHAND_QUANTITIES_ID,ORGANIZATION_TYPE,");
insertBuilder.append("OWNING_ORGANIZATION_ID,TRANSACTION_UOM_CODE,TRANSACTION_QUANTITY,IS_CONSIGNED");
insertBuilder.append("FROM MTL_ONHAND_QUANTITIES_TEMP MOQT ");
insertBuilder.append("WHERE 1=1 AND NOT EXISTS(SELECT 1 FROM MTL_ONHAND_QUANTITIES_DETAIL MOQD WHERE 1=1 AND MOQD.ONHAND_QUANTITIES_ID = MOQT.ONHAND_QUANTITIES_ID)");
String insertSql = insertBuilder.toString();
insertBuilder.delete(0, insertBuilder.length());
try {
return db.execute(insertSql);
} catch (JDBCException e) {
e.printStackTrace();
logBean.setExceptContent(e.getMessage());
return -1;
} catch (Exception e) {
e.printStackTrace();
logBean.setExceptContent(e.getMessage());
return -1;
}
}
你如果有时间的话,可以DEBUG一下,在insertSql执行前这段sql是啥,再复制到plsql中执行一下你就知道问题出在哪儿了。
原因很简单,就是sql在拼接的时候,该有空格或者换行的地方没有,倒数第是哪个append后面需要留一个空格出来,这样后面的IS_CONSIGNED就不会和后面的FROM拼在一起,如果没有这个空格,insertSql中就会出现IS_CONSIGNEDFROM,自然而然找不到FROM关键字了。
还有另一个方法就是在每段待拼接的字符串后面加上"\n"这样拼接的字符串格式就会每段换行。
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("SELECT ID,NAME,AGE");
stringBuilder.append("FROM STUDENT");
System.out.println(stringBuilder.toString());
//输出内容为:SELECT ID,NAME,AGEFROM STUDENT
//会报错ORA-00923
}
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("SELECT ID,NAME,AGE\n");
stringBuilder.append("FROM STUDENT\n");
System.out.println(stringBuilder.toString());
/**
符合要求
输出内容为:
SELECT ID,NAME,AGE
FROM STUDENT
*/
}
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("SELECT ID,NAME,AGE ");
stringBuilder.append("FROM STUDENT");
System.out.println(stringBuilder.toString());
/**
符合要求
输出内容为:
SELECT ID,NAME,AGE FROM STUDENT
*/
}