PHP и Oracle, каково это ... после MySQL. Автоинкремент.

01.11.2007

Прежде чем затронуть такую интересную тему хочу сказать пару слов о том, какой же клиент наиболее удобен для работы с ораклом. Лично мне сразу же посоветовали очень приглянувшийся мне клиент SQL Navigator. Денег стоит, как и все на свете. Что-то начиная с тыщи баксов. Впрочем, не актуально, мы же не мега-крутые разработчики, нам и демка подойдет. Тему лицензионности софта не обсуждаю.

Итак, начнем более подробный разбор автоинкрементных последовательностей. Для начала предположим, что у нас есть база dbdb и мы создаем в ней таблицу table1:

CREATE TABLE dbdb.table1
(
    id          NUMBER (20,0),
    name     VARCHAR2 (50)
)

Теперь, как мы уже знаем из прошлой статьи нам надо создать последовательность, по английски это слово звучит как sequence. Создаем:

CREATE SEQUENCE dbdb.table1_id_sequence
	START WITH  1
	INCREMENT BY  1
	MINVALUE  1

Как вы заметили – ей надо дать имя. На самом деле имя можно давать абсолютно любое, но лучше сразу себя приучить к какой-нибудь системе именования. Мне вот понравилось после имени таблицы писать поле для которого она создается и слово “sequence” через подчеркивание. Вы можете избрать свое, возможно более удобное.

После создания последовательности надо создать триггер, работающий на ее основе. Займемся этим:

CREATE OR REPLACE TRIGGER dbdb.table1_id_trigger
BEFORE INSERT
            ON table1
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW 
begin
   	select table1_id_sequence.nextval into :NEW.id from DUAL;
end;

Воот. Осталось понять, что же эта ахинея означает. Хотя на самом деле ничего сложного. Во-первых выбираем имя триггера, оставлю это на вашей совести. Дальше делаем с виду странную запись “REFERENCING OLD AS OLD NEW AS NEW”. Но. Ничего странного. Все логично. Здесь мы всего лишь уведомляем оракл о том, что далее в теле триггера мы будем использовать псевдоним NEW для обозначения новой формируемой строки, а OLD как старой.

А в теле триггера вставляем следующее значение из последовательности прямо в новую, еще не сформированную строку. Запись “FROM DUAL” фактически ничего не означает. Она нужна лишь для сохранения корректности синтаксиса. DUAL – это некий внутренний системный объект оракла, из которого можно выбирать все под ряд, например так: SELECT 1 FROM DUAL. Та же MySQL нам прощает синтаксис и без использования обязательного слова FROM.

Впрочем, все это вы можете узнать в документации. Сейчас я расскажу как надо составить запрос, что бы вытащить последний вставленный ID. В связке MySQL-PHP нам эту функцию заменяет фукнция mysql_insert_id. А выглядит он до безобразия просто:

SELECT table1_id_sequence.currval FROM DUAL

P.S. Хочу обратить внимание, что currval пишется с двумя R.

Обязательно к прочтению – PHP и Oracle, каково это … после MySQL. Часть 1.


Комментирование этой статьи закрыто

Комментарии [6]

  1. Ноя 1, 07:13 , Евгений

    В PostgreSQL примерно также, только в триггере нет необходимости: мы просто задаём для инкрементного поля значение по-умолчанию равное nextval(‘имя_sequence’::regclass)

    В этой строке «::regclass» приводит строку с именем объекта к самому объекту (преобразование типов, так сказать).

    Или вообще используем встроенный тип SERIAL / BIGSERIAL.

  2. Ноя 1, 19:35 , smart

    Во времена когда мне приходилось работать с Oracle мне достаточно сильно нравились продукты от Toad. Посмотри на досуге: http://www.toadsoft.com/toad_oracle.htm

  3. Ноя 1, 23:10 , Dead Krolik

    Спасибо за мнение :)

  4. Ноя 29, 03:17 , Zhmur

    В 11 версии появилась возможность делать вот так:

    create or replace trigger Trg
    before insert on My_Table for each row
    begin
    :New.Id := My_Seq.Nextval;
    end;

  5. Фев 20, 17:14 , Serge

    А как быть, если в промежуток времени между выполнением INSERT INTO TABLE и SELECT table1_id_sequence.currval FROM DUAL выполнится еще один INSERT от другого пользователя? table1_id_sequence.currval вернет тогда неправильное значение!

  6. Фев 21, 13:00 , Dead Krolik

    Все она правильно вернет. Эта штука действует для каждого соединения.

Комментирование этой статьи закрыто

Кто я


Возраст: 23
Профессия: заяц


Категории


Полезные ссылки


Стишок

Зайчик-зайчик, скок-поскок!
Н-нна тебе дробину в бок!
Не с капустой же мы будем
Жрать на Новый год пирог...

eu-shestakov.livejournal.com