Intereting Posts

объявлять переменные в блоке pl / sql

Я пытаюсь следовать этому руководству для создания блоков pl/sql и я получаю ORA-00922: отсутствует или недействительный параметр в SET orderNumberSEQ... Что я делаю не так?

 declare orderNumberSEQ number(5); userid varchar(20); begin insert into bs_orders (userid, ono, timepurchased) values('lilith', orderNum_seq.NEXTVAL,(SELECT current_timestamp FROM dual)); SET orderNumberSEQ := orderNum_seq.CURRVAL; SELECT userid FROM bs_orders where ono = orderNumberSEQ; end; / 

Вам не нужно использовать SET . Просто

 SELECT orderNum_seq.CURRVAL INTO orderNumberSEQ FROM DUAL; 

будет делать трюк. Или если вы используете oracle11 :

 orderNumberSEQ := orderNum_seq.CURRVAL; 

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

  1. Значение последовательности, возможно, изменилось между вызовом NEXTVAL и CURRVAL. Это приведет к затруднительному обнаружению ошибки, и есть вероятность, что вы получите значение, используемое другим сеансом. Используйте предложение return в инструкции insert для получения фактического вставленного значения.
  2. Имена ваших переменных совпадают с именами столбцов. Это приведет к затруднению обнаружения ошибок в запросах, встроенных в блоки PL / SQL. Убедитесь, что ваши переменные называются по-разному – вы можете префикс их от имени типа, такого как v_userid, а не для userid.
  3. Оператор SELECT внутри блока PL / SQL Oracle требует предложения INTO. Пример:

    SELECT userid INTO v_userid FROM bs_orders WHERE ono = orderNumberSEQ;

  4. Подзапрос для current_timestamp является избыточным. Вы можете использовать простой CURRENT_TIMESTAMP вместо подзапроса для достижения того же результата.

  5. Вместо ручного предоставления типа столбца. Привяжите его к типу точной таблицы, используя нотацию типа%.

    v_userid bs_orders.userid% type;

В следующем коде рассматриваются все 5 вопросов.

 DECLARE v_userid bs_orders.userid%type; -- anchoring the type BEGIN INSERT INTO bs_orders(userid , ono , timepurchased) VALUES('lilith', orderNum_seq.NEXTVAL, CURRENT_TIMESTAMP) RETURNING userid INTO v_userid; -- instead of currval and an additional select -- do whatever you want with v_userid here END; /