Как использовать последовательность в функции в PLSQL? - PullRequest
0 голосов
/ 04 мая 2019
  1. В моей схеме в моем поселении есть столбец ссылочных номеров таблица с нулевым значением типа varchar2, которую я хочу постоянно обновлять.
  2. Затем я создал последовательность с именем ref_seq_num, используя встроенную функцию.
  3. Я хочу использовать его (ref_seq_num) в моей функции get_ref_num для обновления последовательности ref. номер моей таблицы расчетов, тип возвращаемого значения также varchar2, и у меня есть функция, как показано ниже

    CREATE OR REPLACE FUNCTION get_ref_num RETURN settlement.ref_nr %TYPE IS
      v_ref_seq settlement.ref_nr%TYPE;
    BEGIN
      v_ref_seq := to_char(sysdate, 'YYYYMMDD')||LPAD(ref_seq_num.nextval, 8,'0');
      RETURN v_ref_seq; 
    END get_ref_num;
    

Тем не менее, я сталкиваюсь с этим сообщением об ошибке 1/55 PLS-00302: component 'ref_nr' must be declared. Я также попытался изменить тип данных на varchar2, и сообщение об ошибке PLS-00215: String length constraints must be in range (1 .. 32767) Как я могу это исправить?

Ответы [ 2 ]

2 голосов
/ 04 мая 2019

Согласно вашему коду, кажется, что есть таблица с именем SETTLEMENT, но она не содержит столбец REF_NR.

В следующем примере показано, как это сделать:

SQL> create sequence ref_seq_num;

Sequence created.

Таблица, которая содержит столбец REF_NR (который затем используется в функции):

SQL> create table settlement (ref_nr varchar2(20));

Table created.

Ваш код без изменений:

SQL> CREATE OR REPLACE FUNCTION get_ref_num RETURN settlement.ref_nr %TYPE IS
  2    v_ref_seq settlement.ref_nr%TYPE;
  3  BEGIN
  4    v_ref_seq := to_char(sysdate, 'YYYYMMDD')||LPAD(ref_seq_num.nextval, 8,'0');
  5    RETURN v_ref_seq;
  6  END get_ref_num;
  7  /

Function created.

Тестирование:

SQL> select get_ref_num from dual;

GET_REF_NUM
--------------------------------------------------------------------------------
2019050400000001

SQL>
1 голос
/ 04 мая 2019

Если у вас есть столбец с именем ref_nr в таблице settlement, ваш код должен работать правильно. Я думаю, что проблема во втором случае возникает из-за отсутствия части точности данных (должна быть, например, varchar2(16)) для определения переменной как v_ref_seq varchar2. Я бы предпочел использовать числовой тип, такой как number или int, для хранения значений для ref_nr, так как все они числовые, и этот тип данных защищает данные, оставшиеся как числовые. Всякий раз, когда вам нужно выполнить запрос, вы можете использовать функцию to_char, предотвращающую экспоненциальное отображение (select to_char(ref_nr) from settlement).

Более того, если вы используете Oracle 12c версию, вам не нужно создавать такую ​​дополнительную функцию, просто измените вашу таблицу так, чтобы она была последовательностью по умолчанию для столбца:

alter table settlement 
modify ref_nr default to_char(sysdate, 'yyyymmdd')||lpad(ref_seq_num.nextval, 8,'0');
...