首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PreparedStatement +在主键列中选择update +Oracle12c+ ORA-01461

PreparedStatement +在主键列中选择update +Oracle12c+ ORA-01461
EN

Stack Overflow用户
提问于 2016-01-07 13:02:39
回答 2查看 2.1K关注 0票数 14

当尝试执行select for update语句并随后执行insert或update时,我遇到了一个奇怪的问题。我得到了一个奥拉-01461异常。只有在使用最新的ojdbc驱动程序(12.1.0.2)时才会出现这种情况,而在旧版本的驱动程序中,它可以正常工作(12.1.0.1)。

更具体地说,最新的驱动程序似乎在主键字符长度上有某种限制(限制在32个字符),尽管相应的列声明超过32个字符。复制问题的示例代码如下:

代码语言:javascript
复制
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")
);

还有一些java:

代码语言:javascript
复制
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();
      }
    }
  }
}

main方法的第一行创建一个uuid

代码语言:javascript
复制
 UUID.randomUUID().toString();

这是36焦耳长。运行此示例类将产生ORA-01461错误,但将上述行更改为

代码语言:javascript
复制
 UUID.randomUUID().toString().replaceAll("-", "");

这将产生32个字符字符串,将正确运行并将该行插入数据库中。注意,保存上述字符串的"TEST_ID“列是VARCHAR2(40 CHAR),可以同时容纳32和36个字符字符串。将列的长度增加到更大的数字不会有任何改变。

我希望我的示例代码易于阅读和理解,我期待着为这个问题找到一个解决方案/解释。

谢谢!

数据库信息:

代码语言:javascript
复制
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

修改后,可以使用相同的数据运行insert语句,以表明这个问题比看起来更奇怪(关于uuid字符串长度)。以下示例代码在最新的oracle驱动程序中正确执行:

代码语言:javascript
复制
  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();
      }
    }
  }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-20 21:13:40

打开一个SR到oracle,因为这是一个12.1.0.2.0JDBC驱动程序的错误,需要一个补丁来解决它。

票数 3
EN

Stack Overflow用户

发布于 2016-01-07 13:51:58

试图在SQL语句中使用大于4000字节的varchar变量时会发生此错误(限制为4000字节)。

您应该检查uuid变量包含哪些内容,注意可能的编码。

无论如何,像VARCHAR这样存储UUID的数据类型不是一个好主意。

使其工作的解决办法可能是将TEST_ID数据类型从VARCHAR2更改为CLOB (如您在下面的注释中所述,删除PK ),但这不是解决方案。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34655888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档