ple*_*eft 13 java oracle jdbc prepared-statement ora-01461
尝试执行select for update语句然后执行插入或更新时,我遇到了一个奇怪的问题.我得到一个ORA-01461例外.只有在使用最新的ojdbc驱动程序(12.1.0.2)时才会发生这种情况,而在较旧的驱动程序中它可以正常工作(12.1.0.1).
更具体地说,最新的驱动程序似乎在主键字符长度(限制为32个字符)中有某种限制,尽管相应的列声明超过32个字符.复制问题的示例代码如下:
CREATE TABLE "TEST_TABLE" (
"TEST_ID" VARCHAR2(40 CHAR) NOT NULL ENABLE,
"TEST_COMMENT" VARCHAR2(200 CHAR),
CONSTRAINT "TEST_TABLE_PK" PRIMARY KEY ("TEST_ID")
);
Run Code Online (Sandbox Code Playgroud)
还有一些java:
public class DemoUpdatableResultSet {
private static final String DB_URL = "jdbc:oracle:thin:@xxxx:1521/xxxxx";
private static final String DB_USER = "xxx";
private static final String DB_PASS = "xxx";
public static Connection getConnection() throws Exception {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
return conn;
}
public static void main(String[] args) {
final String uuid = UUID.randomUUID().toString();
ResultSet rs = null;
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = getConnection();
String query = "SELECT t.* FROM TEST_TABLE t WHERE t.TEST_ID=? FOR UPDATE";
pstmt = conn.prepareStatement(query, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
pstmt.setString(1, uuid); // set input values
rs = pstmt.executeQuery(); // create an updatable ResultSet
// insert column values into the insert row.
rs.moveToInsertRow(); // moves cursor to the insert row
rs.updateString("TEST_ID", uuid); // updates the 2nd column
rs.updateString("TEST_COMMENT", "Comment for: " + uuid);
rs.insertRow();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
main方法的第一行创建一个uuid
UUID.randomUUID().toString();
Run Code Online (Sandbox Code Playgroud)
这是36个字符长.运行此示例类将产生ORA-01461错误,但将上面提到的行更改为
UUID.randomUUID().toString().replaceAll("-", "");
Run Code Online (Sandbox Code Playgroud)
产生32个字符串的字符串将正确运行并在数据库中插入该行.请注意,保存上述字符串的"TEST_ID"列是VARCHAR2(40 CHAR),可以容纳32和36个字符串.将列的长度增加到更大的数字不会改变任何东西.
我希望我的示例代码易于阅读和理解,我期待着对这个问题的解决方案/解释.
谢谢!
数据库信息:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
"CORE 12.1.0.2.0 Production"
TNS for Linux: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production
Run Code Online (Sandbox Code Playgroud)
稍微修改以运行具有相同数据的insert语句,以表明此问题比看起来更奇怪(关于uuid字符串长度).以下示例代码使用最新的oracle驱动程序正确执行:
public static void main(String[] args) {
final String uuid = UUID.randomUUID().toString();
ResultSet rs = null;
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = getConnection();
String query = "INSERT INTO TEST_TABLE (TEST_ID, TEST_COMMENT) VALUES (?, ?)";
pstmt = conn.prepareStatement(query);
pstmt.setString(1, uuid); // set input values
pstmt.setString(2, "Comment for: " + uuid); // set input values
rs = pstmt.executeQuery();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1359 次 |
| 最近记录: |