没有结果集对象时获取受影响的行数

Posted

技术标签:

【中文标题】没有结果集对象时获取受影响的行数【英文标题】:Getting affected row count when there is no resultset object 【发布时间】:2018-02-14 11:12:27 【问题描述】:

我已经给出了一个 pl/sql 过程,我应该通过 jdbc 从 java 代码中调用它。

public boolean deleteCompany(TimeStamp timestamp, Long companyId)
String str = "call Delete_Company(?,?)";
        CallableStatement statement =  null; 
        boolean deleted = false;
        try
            statement = conn.prepareCall(str);
            statement.setLong(1,companyId);
            statement.setTimestamp(2,timeStamp);
            statement.execute();
            deleted = true;
            return deleted;
        finally
            statement.close();
          

问题是即使我发送了错误的 id 号,它显然会执行语句,因此已删除的变量变为 true。我尝试了 .executeUpdate() 方法来获取受影响的行数,但它不能正常工作,因为在这两种情况下(当删除/没有删除发生时)它检索到 1。我想问题是我的 pl/sql 过程using 只执行删除操作,但不检索任何结果集对象。所以无论是 executeUpdate() 还是 getUpdateCount() 方法都对我没有帮助。我的问题是,即使我没有结果集对象,有什么方法可以获得受影响的行数?

仅供参考:我知道受影响的行数可以作为 pl/sql 过程的输出参数发送,但我无权在 db 端进行任何更改。

【问题讨论】:

【参考方案1】:

由于您无法更改存储过程,因此一种解决方案是执行以下操作

    在调用更新操作之前获取行数(select count(*) from your_tbl where .....) 删除你已经在做的记录 获取删除操作后的行数,并检查受影响的行数是否与#1中的相同(num_rows#1 - num_rows#3)

其他事务仍然会使这种方法有些不可靠,因为它们也可以在步骤 #1 和 #3 之间更改您的表。 如果这对您来说是一个问题,那么您应该使用事务(只需将您的 Java 代码放在事务中)。

【讨论】:

感谢您的回答,但我知道您提到的解决方案。正如我在帖子中所说,我需要在不干扰被调用存储过程@dsp_user 的签名的情况下进行破解。 我已经更新了我的答案(抱歉没有看到最后一部分)【参考方案2】:

您的statement.execute(); 返回一个布尔值,如果执行成功,无论程序在调用时做什么,它总是返回true。此外,您可以参考以下代码了解您正在寻找的内容。

...

    boolean hadResults = cStmt.execute();

    //
    // Process all returned result sets
    //

    while (hadResults) 
        ResultSet rs = cStmt.getResultSet();

        // process result set
        ...

        hadResults = cStmt.getMoreResults();
    

    //
    // Retrieve output parameters
    //
    // Connector/J supports both index-based and
    // name-based retrieval
    //

    int outputValue = cStmt.getInt(2); // index-based

    outputValue = cStmt.getInt("inOutParam"); // name-based

...

【讨论】:

Prepared/CallableStatement.execute()如果第一个结果是结果集则返回true,如果是更新计数则返回false,如果成功则并不总是返回true;失败总是会导致异常。 @MarkRotteveel 我的回答专门针对他试图调用过程的 OP,在这种情况下,调用成功时它总是返回 true 可能适用于 Oracle,但一般不适用于 JDBC。

以上是关于没有结果集对象时获取受影响的行数的主要内容,如果未能解决你的问题,请参考以下文章

仅执行动态查询以获取受影响的行数

C#中对SQl数据库进行插入操作,有返回受影响的行数,执行结果是“添加成功”但是在数据困中却没有数据

获取 Java 结果集中的行数

受 Microsoft JDBC 驱动程序的 SELECT INTO 查询影响的行数

SQLAlchemy ResultProxy.rowcount 不应为零

sql server查询结果集复制出来的行数和在SSMS上的行数不一致