PreparedStatement.executeUpdate() 不适用于 Oracle

Posted

技术标签:

【中文标题】PreparedStatement.executeUpdate() 不适用于 Oracle【英文标题】:PreparedStatement.executeUpdate() is not working for Oracle 【发布时间】:2017-08-09 16:28:47 【问题描述】:

我使用PreparedStatement 来执行更新查询。 以下是查询:

String callersUpdateQuery = "update W67U999S a set pcrdattim= ? where exists (select b.CRDATTIM, b.RECORDCD, b.CRNODE, b.UNITCD, b.WRKTYPE from W03U999S b where a.PCRDATTIM = ? and a.CCRDATTIM = b.CRDATTIM and a.CRECORDCD = b.RECORDCD and a.CCRNODE = b.CRNODE and a.PRECORDCD = 'F' and a.PCRNODE = '01' and b.WRKTYPE = 'CALLER' and b.UNITCD=? and a.crecordcd='T')";

下面是应该更新记录的java代码:

preparedStatement = dbConnection.prepareStatement(callersUpdateQuery);
                preparedStatement.setString(1,newFolderCrdattim);  
                preparedStatement.setString(2,crdattim);  
                preparedStatement.setString(3,businessAreaName.trim());
                int j = preparedStatement.executeUpdate();

但是preparedStatement.executeUpdate() 没有更新所需的行并将更新的行数返回为零。奇怪的是,当我在数据库端执行相同的 sql 查询时,记录正在更新。 我的数据库是 Oracle,应该更新的表的架构如下:

Name        Null     Type       
----------- -------- ---------- 
PCRDATTIM   NOT NULL CHAR(26)   
PRECORDCD   NOT NULL CHAR(1)    
PCRNODE     NOT NULL CHAR(2)    
RECORDTYPE  NOT NULL NUMBER(3)  
CCRDATTIM   NOT NULL CHAR(26)   
CRECORDCD   NOT NULL CHAR(1)    
CCRNODE     NOT NULL CHAR(2)    
CRDATTIM    NOT NULL CHAR(26)   
LINKRULE_ID NOT NULL NUMBER(14) 

谁能猜出代码或查询有什么问题?

【问题讨论】:

“谁能猜到...?” 当然,我猜测这与crdattim的值有关和/或businessAreaName 仅供参考: 不要在exists 子句中对a 设置条件。它们应该作为updatewhere 子句的一部分在外面。 b.UNITCD的类型和大小是多少?也许this 可能会有所帮助。 b.UNITCD 的类型是CHAR。仅供参考,都是 CHAR 类型。 【参考方案1】:

首先,您是否检查了您在 where 子句中用作条件的 select 上是否存在元组?

如果有行被返回。该问题可能与您正在执行更新语句的事务有关。仔细检查您的事务模式以及它是否真的被提交。

作为查询优化建议,我将语句更改为:

String callersUpdateQuery = 
    "update W67U999S a 
     set pcrdattim= ? 
     where 
            a.PCRDATTIM = ? 
        and a.PRECORDCD = 'F' 
        and a.PCRNODE   = '01' 
        and a.CRECORDCD ='T'

        and exists (
            select 
                b.CRDATTIM, 
                b.RECORDCD, 
                b.CRNODE, 
                b.WRKTYPE 
            from W03U999S b 
            where 
                  b.CCRDATTIM = a.CRDATTIM 
              and b.CRECORDCD = a.RECORDCD 
              and b.CCRNODE = a.CRNODE 
              and b.WRKTYPE = 'CALLER' 
              and b.UNITCD=? 
        )";

这样,您将首先从 a 减少元组,然后使用它将 b 元组缩小到匹配的元组。

【讨论】:

通过 SQL 编辑器成功执行具有相同值的相同查询。 exists 是否会导致这里出现问题? 但在 SQL 编辑器中,自动提交功能可能处于活动状态。自动提交更新或您正在查看的数据对您可见,因为您处于同一事务中。如果您的程序没有主动提交,您的事务将在其执行结束时回滚。 Oracle CHAR 类型是这里的罪魁祸首。我要更新的列是 CHAR 类型。这就是问题的根源。此链接帮助我找出解决方案:***.com/questions/5332845/… 很高兴收到反馈!因此,SELECT 语句无法正常工作(SQL 编辑器以某种方式处理列的修剪)。将列从 CHAR 移动到 VARCHAR 将是首选解决方案。【参考方案2】:

Oracle CHAR 类型是这里的罪魁祸首。我要更新的列的类型为CHAR。这就是问题的根源。此链接帮助我找出解决方案:Oracle JDBC and Oracle CHAR data type

【讨论】:

以上是关于PreparedStatement.executeUpdate() 不适用于 Oracle的主要内容,如果未能解决你的问题,请参考以下文章