28 марта, суббота 21:02
Bankir.Ru

Объявление

Свернуть
Пока нет объявлений.

Вызов оракловой процедуры

Свернуть
X
  • Фильтр
  • Время
  • Показать
Очистить всё
новые сообщения

  • Вызов оракловой процедуры

    Добрый день.

    Возможно дилетантский вопрос, но я уже пол дня бьюсь...

    В PayDoc нужно выполнить оракловую процедуру, и получить результаты аут-параметра.


    Дёргаю следующий кусок кода:

    {
    ...
    CurOperNum := MemOrder.OperNum;

    if not InitSp('hcf_suspest_docs.add_to_table') //проверяем процедуру
    {
    PutMessage('Не проинициализирована пакетная процедура hcf_suspest_docs.add_to_table');
    exit;
    };

    SetLongintParamSp('iOperNum',CurOperNum); //инитим параметр
    ExecSp; //выполняем

    result := GetLongintParamSp('oResult'); //получаем значение аут-параметра

    //всё, конец
    }

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

Название:	message.JPG 
Просмотров:	1 
Размер:	73.8 Кб 
ID:	4169309

    При том, что в переменной оказывается 0.

    Переменные передающие и принимающие значения в PayDoc объявлены как LongInt, в вызываемой оракловой процедуре как Number.

    Спасибо.

  • #2
    Не очень понял, в чем проблема? Все перечисленное - это нормальное, штатное поведение Кворума для подобной ситуации (при условии конечно, что 123 - это правильный ответ от хранимой процедуры). А что не нравится, что должно было быть?
    Суть вот в чем. Result - это переменная, предопределенная ВНУТРИ любой атлантисовской функции. Она предназначена для передачи наружу результата функции, и снаружи не существует (точнее снаружи существует другая переменная с именем result, принадлежащая уже другой, наружной функции, и имеющая совсем другое значение).

    Поэтому вот такая конструкция:
    result:=...какое-то значение; //все, конец
    }
    эта конструкция делает две вещи
    1. Передает значение переменной result наружу в качестве значения вызываемой функции.
    2. Заканчивает выполнение функции, очищает память, отведенную под локальные переменные функции, в том числе под ее локальную result.

    Это объясняет, почему мы видим значение переменной = 0 - функция завершилась, память очищена. Вот если вместо строчки "//все, конец", перед } вставить еще какие-то исполняемые операторы, тогда во время их исполнения переменная result будет еще хранить возвращенное из оракловой процедуры значение.

    Теперь что касается картинки. Это нормальное поведение Кворума. Если мы вручную по F11 или F12 вызываем какую-то функцию, которая через переменную result возвращает значение, Кворум просто показывает это значение в диалоговом окне. А что ему еще остается делать? Другой обработчик значения функции программистом ведь не определен...

    Комментарий


    • #3
      Спасибо большое.

      Вот всё перепробовал, а то что Result - зарезервированное слово не догадался.

      Комментарий


      • #4
        Да, наверное именно так правильно сказать - зарезервированное слово.
        Означающее имя некоей хитрой локальной переменной, обладающей некими особыми свойствами по сравнению с обычными переменными.

        Комментарий


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

          Предупреждение 1
          Вызываемая через механизм InitSP/ExecSP хранимая процедура не должна быть "перегруженной". Т.е. на сервере Оракла должна быть только одна единственная процедура с таким именем, не должно существовать несколько разных реализаций процедуры с одним именем, но разными наборами параметров.
          Из-за особенностей передачи параметров процедуры из Атлантиса в Оракл, сервер не может правильно решить, какой из вариантов "перегруженной" процедуры вызвать.

          Комментарий


          • #6
            Предупреждение 2
            При передаче параметров в оракловую хранимую процедуру через вызовы SetXXXXParamSP нужно быть очень осторожным с передачей в Оракл значений функций.
            Желательно, чтобы при вызове SetXXXXParamSP (и вообще между вызовами InitSp и ExecSP) использовались только константы и простые переменные.

            Пример неправильного кода:
            Код:
            InitSP('MY_Procedure');
            SetStringParamSP('iAccount', GetNewAccNum(DbAcc,DbCurrCode));
            SetDateParamSP('iDate', ProDate);
            ExecSP;
            Вышеприведенный код неверный, хранимая процедура MY_Procedure в результате него выполнена НЕ будет, потому что в середине куска кода вызывается функция GetNewAccNum, которая в свою очередь на самом деле является лишь оболочкой для вызова хранимой процедуры TwinPln.GetNewAccNum. Внутри функции GetNewAccNum первым же делом выполняется оператор
            InitSP('TwinPln.GetNewAccNum');
            В результате этого, наш предыдущий вызов InitSP('MY_Procedure') оказался "забытым". Когда дело дойдет до выполнения оператора ExecSP - он выполнит ту процедуру, которая последний раз инитилась, то есть повторно выполнит TwinPln.GetNewAccNum. А наша MY_Procedure так и не запустится!

            Пример правильного кода:
            Код:
            var MyAccount : string;
            ...
            {
            ...
            MyAccount := GetNewAccNum(DbAcc,DbCurrCode);
            InitSP('MY_Procedure');
            SetStringParamSP('iAccount', MyAccount);
            SetDateParamSP('iDate', ProDate);
            ExecSP;

            Комментарий

            Обработка...
            X