Отправка блока PL / SQL в базу данных с использованием OCI всегда возвращает rows_affected = 1 (ORACLE DB) - PullRequest
0 голосов
/ 14 июля 2020

Я пишу клиента в C, который отправляет запрос в Oracle БД, и когда я пытаюсь выбрать количество затронутых им строк, я всегда получаю значение 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; ";

Я выполняю его, используя OCIStmtExecute функцию OCI с 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.

Есть ли что-нибудь, что нужно делать иначе при выполнении запроса в этой форме?

1 Ответ

1 голос
/ 15 июля 2020

К сожалению, все устроено так. Ваш блок может удалять 20 строк, затем обновлять 10 и т. Д. c. SQL% ROWCOUNT всегда возвращает 1 после успешного выполнения блока PL / SQL с немедленным выполнением. Вы можете рассмотреть возможность вызова SQL% ROWCOUNT внутри блока Dynami c, а затем вернуть это значение и использовать его.

Вы можете увидеть это поведение в моем тривиальном скрипте Live SQL: https://livesql.oracle.com/apex/livesql/s/kdh6dang21mt8eumn4x6wv0ct

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


count = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...