PHP и Oracle, каково это ... после MySQL. Автоинкремент.
Прежде чем затронуть такую интересную тему хочу сказать пару слов о том, какой же клиент наиболее удобен для работы с ораклом. Лично мне сразу же посоветовали очень приглянувшийся мне клиент 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.
Комментарии [4]
-
В PostgreSQL примерно также, только в триггере нет необходимости: мы просто задаём для инкрементного поля значение по-умолчанию равное nextval(‘имя_sequence’::regclass)
В этой строке «::regclass» приводит строку с именем объекта к самому объекту (преобразование типов, так сказать).
Или вообще используем встроенный тип SERIAL / BIGSERIAL.
-
Во времена когда мне приходилось работать с Oracle мне достаточно сильно нравились продукты от Toad. Посмотри на досуге: http://www.toadsoft.com/toad_oracle.htm
-
Спасибо за мнение :)
Ноя 28, 23:17 , Zhmur
В 11 версии появилась возможность делать вот так:
create or replace trigger Trg
before insert on My_Table for each row
begin
:New.Id := My_Seq.Nextval;
end;
2008-10-11 3:35 am , Оставьте свой отзыв