使用 OCI 始终将 PL/SQL 块发送到数据库 return rows_affected=1 (ORACLE DB)

Sending PL/SQL block to db using OCI always return rows_affected=1 (ORACLE DB)

我正在用 C 编写一个客户端,它向 Oracle DB 发送一个查询,当我尝试对受它影响的行数进行采样时,我得到的值总是 1。 这是查询:

char * query =    "BEGIN "\
                  "INSERT INTO table_name ( field_1, field_2, id, field_3 ) VALUES ( :1, :2, :3, 1 );"\
                  "EXCEPTION "\
                  "when dup_val_on_index then "\
                  "UPDATE table_name SET field_1 =:4, field_2 =:5, field_3 = 1 where id = :6 and field_4 <= :7;"\
                  "END; ";

我使用 OCI 的 OCIStmtExecute 函数和 OCI_COMMIT_ON_SUCCESS 来执行它,为了对受影响的行进行采样,我做了:

ub4 update_count;
OCIAttrGet(stmthp, OCI_HTYPE_STMT, &update_count, 0, OCI_ATTR_ROW_COUNT, ctx->hp);

出于某种奇怪的原因,update_count 始终为 1。 这很奇怪,因为如果我以完全相同的方式发送一个简单的更新或插入查询,我会在 update_count.

中得到正确的结果

以这种形式执行查询时,有什么不同之处需要做的吗?

不幸的是事情就是这样。您的块可能会删除 20 行,然后更新 10 行,依此类推。 SQL%ROWCOUNT 总是 returns 1 在通过立即执行成功执行 PL/SQL 块 运行 之后。您可能会考虑在动态块中调用 SQL%ROWCOUNT,然后 return 该值并使用它。

您可以在我简单的 LiveSQL 脚本中看到此行为:https://livesql.oracle.com/apex/livesql/s/kdh6dang21mt8eumn4x6wv0ct

begin 
   execute immediate 'begin null; end;'; 
   dbms_output.put_line ('count = ' || sql%rowcount); 
end;   
/


count = 1