Как создать переменную, к которой можно получить глобальный доступ -oracle - PullRequest
0 голосов
/ 17 января 2019
CREATE OR REPLACE PROCEDURE cost_proportion(
    p_assignment_id IN NUMBER,
    p_proportion    IN NUMBER,
    p_old_value     IN NUMBER,
    p_cost_alloc_id IN NUMBER,
    p_cost_code     IN VARCHAR2,
     p_date_from in date,
    p_flag IN VARCHAR2 )
IS
  PRAGMA AUTONOMOUS_TRANSACTION;
  v_flag NUMBER :=0;

BEGIN

  IF p_flag = 'V' 
  THEN
    --            IF p_old_value > 0 THEN

            DELETE
            FROM cost_temp
            WHERE 1=1
               and cost_code = p_cost_code
              --AND
            AND assignment_id = p_assignment_id;



    IF SQL%ROWCOUNT = 0 THEN
          DELETE
          FROM cost_temp
          WHERE cost_allocation_id = p_cost_alloc_id
          AND assignment_id        = p_assignment_id;
    END IF;
    --            END IF;
    INSERT
    INTO cost_temp VALUES
      (
        p_assignment_id,
        p_proportion,
        p_old_value,
        p_cost_alloc_id,
        p_cost_code,
        p_flag
      );
    COMMIT;
  ELSIF p_flag = 'P' THEN
    DELETE FROM ecost_temp WHERE assignment_id = p_assignment_id;
    INSERT INTO cost_temp
          SELECT assignment_id,
            proportion * 100,
            0,
            cost_allocation_id,
            b.segment1
            || '|'
            || b.segment3
            || '|'
            || b.segment2
            || '|'
            || b.segment4
            || '|'
            || b.segment6,
            p_flag
          FROM pay_cost_allocations_f a,
            pay_cost_allocation_keyflex b
          WHERE a.cost_allocation_keyflex_id = b.cost_allocation_keyflex_id
          AND a.assignment_id                = p_assignment_id
          AND sysdate BETWEEN a.effective_start_date AND a.effective_end_date;

    COMMIT;


  ELSIF p_flag = 'D' THEN
        DELETE
        FROM cost_temp
        WHERE cost_code = p_cost_code
        AND proportion  = p_proportion;
    COMMIT;
  END IF;
END;

В приведенном выше запросе я хочу, чтобы всякий раз, когда выполнялся раздел p_flag = 'P', устанавливалось значение переменной. Это должно быть фиксированное значение, к которому я смогу получить доступ при следующем запуске этой процедуры. это возможно?

скажем, например: v_flag = 2, когда выполняется p_flag = 'P'.

и когда эта процедура снова вызывается другим блоком, это значение остается v_flag = 2

Ответы [ 2 ]

0 голосов
/ 17 января 2019

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

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

0 голосов
/ 17 января 2019

В PL / SQL глобальная переменная может существовать только в пакете. Это потому, что PL / SQL инициализирует переменные уровня процедуры каждый раз, когда вызывается процедура. Только пакет позволяет нам определять переменную вне области действия процедуры.

Этот пакет игрушек будет сохранять значение n при нескольких вызовах до gvar_test.incr().

create or replace package gvar_test as
     procedure incr (p_in in number, p_out out number);
end gvar_test; 
/
create or replace package body gvar_test as
     n pls_integer;

     procedure incr (p_in in number, p_out out number) is
     begin
         n := n + p_in;
         p_out := n;
     end incr;
begin
    -- initialise variable first time package is called 
    n := 0;
end gvar_test; 
/

Глобальные переменные - сложная вещь. Многие люди считают их использование плохой практикой, в первую очередь потому, что очень легко потерять след из состояния. Это особенно верно, когда мы работаем с веб-приложениями, проходящими через пул соединений. Переменные PL / SQL хранятся в памяти сеанса, поэтому бесполезны для сохранения состояния между вызовами в среде, где каждый вызов может быть передан случайному сеансу. В этом случае вы должны использовать глобальные контексты приложения для хранения значения. Они доступны через сеансы базы данных (поэтому вам нужно быть осторожным с идентификаторами). Узнать больше .

Помимо этого, рассмотрите, являются ли переменные в памяти (будь то PL / SQL или контекст приложения) безопасным подходом. Если вы отслеживаете какой-либо рабочий процесс или состояние процесса, обычно лучше сохранить его в таблице, хотя бы только для целей восстановления.

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