Tôi có vấn đề lạ khi cố gắng thực thi chọn câu lệnh cập nhật và sau đó thực hiện sau đó chèn hoặc cập nhật. Tôi nhận được một ngoại lệ ORA-01461. Điều này chỉ xảy ra khi sử dụng trình điều khiển ojdbc mới nhất (12.1.0.2), trong khi ở chế độ cũ hơn, nó hoạt động tốt (12.1.0.1).PreparedStatement + Chọn để cập nhật + Oracle 12c + ORA-01461 trong cột khóa chính
Cụ thể hơn, trình điều khiển mới nhất dường như có một số giới hạn trong độ dài ký tự chính (giới hạn 32 ký tự) mặc dù cột tương ứng được khai báo hơn 32 ký tự. mẫu mã để tái tạo các vấn đề như sau:
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")
);
Và một số 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();
}
}
}
}
Dòng đầu tiên của phương pháp chính tạo ra một uuid
UUID.randomUUID().toString();
đó là dài 36 ký tự. Chạy lớp mẫu này sẽ tạo ra một lỗi ORA-01.461, nhưng thay đổi dòng nêu trên để
UUID.randomUUID().toString().replaceAll("-", "");
trong đó sản lượng đến 32 ký tự chuỗi sẽ chạy một cách chính xác và chèn hàng trong cơ sở dữ liệu. Lưu ý rằng cột "TEST_ID" trong đó chuỗi trên được lưu là VARCHAR2 (40 CHAR) và có thể chứa cả hai chuỗi ký tự 32 và 36. Việc tăng chiều dài của cột lên những con số lớn hơn sẽ không thay đổi gì cả.
Tôi hy vọng mã mẫu của tôi dễ đọc và dễ hiểu và tôi mong chờ giải pháp/giải thích cho vấn đề này.
Cảm ơn!
Cơ sở dữ liệu Thông tin:
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
Modified hơi để chạy một tuyên bố chèn với cùng một dữ liệu để chứng minh rằng vấn đề này là kỳ lạ hơn có vẻ như (về độ dài chuỗi uuid). Mẫu mã sau đây thực hiện một cách chính xác với trình điều khiển oracle mới nhất:
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();
}
}
}
Xin chào, đã chỉnh sửa bài đăng đầu tiên của tôi và thêm thông tin cơ sở dữ liệu. Cảm ơn! – pleft
Bạn có thể thử thay thế ký hiệu gạch nối bằng một ký tự khác (ví dụ '0' hoặc' a') thay vì chuỗi rỗng? Chỉ cần hiểu nếu vấn đề thực sự là kích thước ... Điều gì sẽ xảy ra? –
Chắc chắn, chỉ cần thử nó, cùng một lỗi xảy ra ORA-01461, xin vui lòng xem chỉnh sửa của tôi với chức năng chính mới mà không chèn. – pleft