Вызов процедуры возвращает успех, но в базе ничего не изменилось

Я пытаюсь вызвать хранимую процедуру с php-страницы, но не получаю желаемого результата.

Я использую oci с php, выполнение запроса выглядит так:

function executeQuery($c, $query){
    $stid = oci_parse($c, $query);
    if (!$stid) {
        $e = oci_error($c);
        trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
    }
    $response['success'] = oci_execute($stid);
    if (!$response['success']) {
        $e = oci_error($stid);
        $response['error'] = $e;
        return $response;
        trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
    }
    //oci_commit($c); //auto commit is by default with oci_execute but I've tried this too. 
    oci_free_statement($stid);
}

Если мой $query является вставкой, он работает нормально и фиксирует вставку, но когда это CALL MY_PROC('VAR1, 'VAR2', VAR3'), $response['success'] верно, но ничего не изменилось базу данных.

И если я выполню CALL MY_PROC('VAR1', 'VAR2', VAR3') в редакторе TOAD и зафиксирую, все будет работать, как и ожидалось, я увижу результаты в базе данных. Но не тогда, когда я вызываю свою процедуру из php.

Я пробовал использовать EXECUTE вместо CALL, добавляя COMMIT; в конце запроса, и oci_commit($c) это все еще не влияет на базу данных.

  • Что я делаю не так? Вероятно, это проблема фиксации?
  • Что я могу сделать, чтобы получить ошибки вместо «успеха»?
  • Возможно, вызовы процедур ведут себя иначе, чем вставки и выборки?

Хранимые процедуры вызывают пакет, который я не писал сам и который имеет параметры out. Может быть, поэтому я не получаю ошибок? (Опять же, когда я запускаю его в жабе с теми же значениями, он работает нормально и не показывает особых ошибок).

Моя процедура выглядит так:

CREATE OR REPLACE MY_PROC(
    VAR1 IN VARCHAR2,
    VAR2 IN VARCHAR2,
    VAR3 IN VARCHAR2
  )
  IS

  BEGIN
    ERROR_CODE := NULL; --//inherited from the packages, don't really know what do do with them
    ERROR_MSG := NULL;

    IF VAR2 = NULL THEN
      VAR2 := 'DEFAULT';
    END IF;
    PKG_USER.CREATE_USER(VAR1, VAR2, VAR3, ERROR_CODE, ERROR_MSG);

    IF (ERROR_CODE != NULL OR ERROR_MSG != NULL) THEN
      DBMS_OUTPUT.PUT_LINE('ERROR_CODE : ' || ERROR_CODE);
      DBMS_OUTPUT.PUT_LINE('ERROR_MSG: ' || ERROR_MSG);
      RAISE PROGRAM_ERROR; --//tried doing this to catch the errors but doesn't work
    END IF;
  END;
/

Я предполагаю, что часть проблемы связана с этими параметрами вывода ошибок, но, опять же, он отлично работает без ошибок, когда я запускаю в нем TOAD.

EDIT: я только что понял, что если я попытаюсь вызвать процедуру, которая не существует, например CALL MYY_PROC(), она все равно не вернет ошибку и возвращает "успех".

Следует также отметить, что я вызываю несколько процедур в различных базах данных. На всех других базах, кроме этой, я обычно получаю ошибки, и вызов процедуры, которая не существует по праву, возвращает:

ORA-06576: not a valid function or procedure name

Так что, по-моему, это может быть две вещи: ошибки копирования-вставки (которые я сейчас проверяю) или некоторые настройки базы данных, такие как @cdb_dba.


Кстати, платформа, для которой я это разрабатываю, использует php4. Очевидно, это не мой выбор, не спрашивайте.


person Teleporting Goat    schedule 28.02.2019    source источник
comment
Убедитесь, что вы подключаетесь к правильной БД   -  person asiby    schedule 28.02.2019
comment
Похоже, что COMMIT не происходит после выполнения хранимой процедуры.   -  person Bob Jarvis - Reinstate Monica    schedule 28.02.2019
comment
@asiby Спасибо. Да, да, как я уже сказал, INSERT работает, и я вижу эффект на базе.   -  person Teleporting Goat    schedule 28.02.2019
comment
Две вещи, которые нужно проверить: 1. Убедитесь, что выход сервера включен. Вы можете сделать это, добавив set serveroutput on; в начало вашей процедуры. Добавьте его прямо перед оператором CREATE OR REPLACE. 2. Вы входите в Toad, используя ту же схему, которая вызывает процедуру с php-страницы? Вы должны увидеть ошибки, если у схемы приложения нет разрешений на вызов процедуры, но на это стоит обратить внимание. Вы также можете добавить фиксацию к своей процедуре в конце вашего случая IF. Такие приложения, как Toad, многое делают в фоновом режиме, и они могут автоматически фиксировать ваши изменения.   -  person 1991DBA    schedule 28.02.2019
comment
Вместо call my_proc попробуйте begin my_proc; end;. Вызов хранимых процедур Oracle с помощью PHP   -  person Ponder Stibbons    schedule 28.02.2019
comment
@cdb_dba Да, та же схема. Я попытался добавить фиксацию внутри процесса, это не сработало.   -  person Teleporting Goat    schedule 28.02.2019
comment
замените это условие: ERROR_CODE != NULL OR ERROR_MSG != NULL на это: ERROR_CODE IS NOT NULL OR ERROR_MSG IS NOT NULL. что-либо != NULL всегда оценивается как NULL (ложь), поэтому оператор IF и оператор RAISE никогда не выполняются.   -  person krokodilko    schedule 28.02.2019
comment
@cdb_dba Смотрите мое редактирование, похоже ли это на что-то связанное с serveroutput?   -  person Teleporting Goat    schedule 28.02.2019
comment
Скорее всего нет. serveroutput связан с выводом пакета DBMS_OUTPUT. Этот параметр определяет, будет ли вывод, созданный пакетом DBMS_OUTPUT, распечатываться на терминале. Не уверен, почему вы не получите ошибку при попытке вызвать несуществующую процедуру... для меня это ново. Это может быть связано с обработкой исключений на стороне приложения? Я предполагаю, что он всегда отображает ошибку от Toad, поэтому я бы посмотрел, как обрабатываются исключения/ошибки. Точки останова будут вашим другом здесь.   -  person 1991DBA    schedule 28.02.2019
comment
@cdb_dba Хорошо, я нашел свою ошибку ... как и все проблемы, которые кажутся неразрешимыми, это была самая глупая из ошибок. Должен ли я тогда удалить свой вопрос?   -  person Teleporting Goat    schedule 28.02.2019
comment
Оглядываясь назад, простые вопросы могут показаться глупыми, но поверьте мне, когда я скажу, что вы не первый человек, решивший подобную проблему, и вы не будете последним. Если чей-то комментарий помог вам устранить ошибку, я бы посоветовал им опубликовать свой комментарий в качестве ответа, чтобы вы могли пометить его как таковой. Таким образом, когда другой новый предприимчивый разработчик столкнется с похожей проблемой, он может столкнуться с вашим вопросом, и это также может быть полезно для них. :) Мы все с чего-то начинаем, просто посмотрите на мою историю вопросов, если вы мне не верите, лол! Рад, что ты разобрался.   -  person 1991DBA    schedule 28.02.2019


Ответы (1)


Ну, я чувствую себя глупо, но, как оказалось, если ваша переменная $query равна null, oci_execute всегда будет возвращать успех.

Моя переменная не называлась $query: я установил (и повторил для подтверждения) $queryProcFTTx, но выполнил $queryProcFttx. Меня обманул VSCode, который выделил оба значения, когда я дважды щелкнул переменную, игнорируя регистр.

person Teleporting Goat    schedule 28.02.2019