объявить переменные в блоке pl / sql - PullRequest
2 голосов
/ 12 декабря 2011

Я пытаюсь следовать этому руководству для создания 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;
/

Ответы [ 2 ]

4 голосов
/ 12 декабря 2011

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

SELECT orderNum_seq.CURRVAL INTO orderNumberSEQ FROM DUAL;

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

orderNumberSEQ := orderNum_seq.CURRVAL;
3 голосов
/ 12 декабря 2011

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

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

    ВЫБРАТЬ идентификатор пользователя INTO v_userid ОТ bs_orders WHERE ono = orderNumberSEQ;

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

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

    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;
/
...