За последние 24 часа нас посетили 18429 программистов и 1623 робота. Сейчас ищут 1303 программиста ...

Есть ли аналог для PDO::lastInsertId?

Тема в разделе "Oracle Database", создана пользователем denisKa, 22 мар 2012.

  1. denisKa

    denisKa Активный пользователь

    С нами с:
    4 сен 2007
    Сообщения:
    46
    Симпатии:
    0
    Здравствуйте!

    По Oracle не силён.

    Соединяюсь с БД через PDO и есть метод PDO::lastInsertId. В документации написано, что если драйвер не поддерживает этот метод, то будет вызвана ошибка IM001 SQLSTATE.

    Драйвер для Oracle не поддерживает этот метод.

    Есть ли аналого этого метода, чтобы при INSERT получать идентификатор текущей записи и не делать SELECT на получение ID текущей записи?
     
  2. AndreJM

    AndreJM Активный пользователь

    С нами с:
    25 янв 2012
    Сообщения:
    522
    Симпатии:
    0
    Если мне не изменяет память, то Оракловые конструкции позволяют делать INSERT INTO ..... RETURNING ..
    То есть вы можете вернуть результат инкрементированного ключа/индекса или чего там у вас.
     
  3. runner

    runner Активный пользователь

    С нами с:
    16 апр 2010
    Сообщения:
    343
    Симпатии:
    1
    Адрес:
    Ташкент
    В Oracle для генерации уникальных ключей используются последовательности(sequence).
    Для генерации ключа служит конструкция название последовательности.NEXTVAL.Таким образом, чтобы получить код вставленной записи нужно выполнить запрос
    insert into table name (id,name,.. ) values (название последовательности.NEXTVAL,'gghh',..) RETURNING ID INTO NewId.

    Для дальнейшего изучения поищи:
    oracle sequence nextval RETURNING
     
    torm84 нравится это.
  4. denisKa

    denisKa Активный пользователь

    С нами с:
    4 сен 2007
    Сообщения:
    46
    Симпатии:
    0
    Спасибо за ответы.

    Да, я также наткнулся на RETURNING, но я пока не могу решить проблему его использования.

    Выполняю SQL-скрипт в Home -> SQL Workshop -> SQL Commands (Web-панель Oracle)
    Код (Text):
    1. INSERT INTO tbl (id, first_name, ....) VALUES(users_seq.NEXTVAL, 'иван', ...) RETURNING id INTO :ID
    Появляется модальное окно, в котором нужно заполнить поле ":ID". И только после этого запись вставляется.

    Выполняю SQL-запрос
    Код (Text):
    1. INSERT INTO tbl (id, first_name, ....) VALUES(users_seq.NEXTVAL, 'иван', ...) RETURNING ID INTO NewID
    получаю ответ
    Выполняю SQL-запрос
    Код (Text):
    1. INSERT INTO tbl (id, first_name, ....) VALUES(users_seq.NEXTVAL, 'иван', ...) RETURNING ID
    получаю ответ
    Выполненяю запрос в PHP
    Код (Text):
    1. INSERT INTO tbl (id, first_name, ....) VALUES(users_seq.NEXTVAL, 'иван', ...) RETURNING id INTO :ID
    И запись добавляется только после того, как в :ID передаю любое случайное число и в ответ ничего не приходит.

    Я так понимаю, что RETURNING id аналогично SELECT users_seq.CURVAL FROM tbl?
     
  5. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.105
    Симпатии:
    1.243
    Адрес:
    там-сям
    stmt:bindParam() используешь?
     
  6. runner

    runner Активный пользователь

    С нами с:
    16 апр 2010
    Сообщения:
    343
    Симпатии:
    1
    Адрес:
    Ташкент
    Сам я не силен в Oracle, но то что прочитал сводится к следующему: в коде
    Код (Text):
    1.  
    2. INSERT INTO tbl (id, first_name, ....) VALUES(users_seq.NEXTVAL, 'иван', ...) RETURNING id INTO :NewID
    NewID это название переменной. Так что сначала нужно написать хранимую процедуру вставки новой записи и определить в ней эту переменную. Ну и далее использовать эту процедуру для вставки. Так что проще просто получить значение id и потом использовать в запросе вставки новой записи:
    select users_seq.NEXTVAL from dual
     
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.105
    Симпатии:
    1.243
    Адрес:
    там-сям
    runner, нах не надо процедуру. ради каждого инсерта процедуру городить слишком жирно будет. максимум окружить sql-выражение блочными скобками begin - end

    топикстартер пишет, что пытается применить insert-returning но с получением нового значения проблемы.
    я спрашиваю ЕГО: как ты вызываешь запрос на выполнение, как привязываешь переменную?
    это уже относится не к синтаксису Oracle, а к интерфейсу PDO
     
  8. denisKa

    denisKa Активный пользователь

    С нами с:
    4 сен 2007
    Сообщения:
    46
    Симпатии:
    0
    Да, действительно это уже излишества писать ещё один триггер. Тогда уж лучше обычный SELECT выполнить.

    Нет.

    Собственно сам PHP код в изначальном виде:
    Код (Text):
    1. $post = array( 'first_name' => 'Name',
    2.                'last_name' => 'Surname',
    3.                'mobile_phone' => 9133333333,
    4.                'email' => 'mail@domain.com' );
    5.  
    6. $sth = $dbh->prepare('INSERT INTO users (first_name, last_name, mobile_phone, email)
    7.                       VALUES(:first_name, :last_name, :mobile_phone, :email)');
    8.  
    9. $sth->execute($post);
    Код с использованием RETURNING id INTO :ID:
    Код (Text):
    1. $post = array( 'first_name' => 'Name',
    2.                'last_name' => 'Surname',
    3.                'mobile_phone' => 9133333333,
    4.                'email' => 'mail@domain.com',
    5.                'id' => rand(1,99999999) );
    6.  
    7. $sth = $dbh->prepare('INSERT INTO users (id, first_name, last_name, mobile_phone, email)
    8.                       VALUES(users_seq.NEXTVAL, :first_name, :last_name, :mobile_phone, :email)
    9.                       RETURNING id INTO :ID');
    10.  
    11. $sth->execute($post);
     
  9. denisKa

    denisKa Активный пользователь

    С нами с:
    4 сен 2007
    Сообщения:
    46
    Симпатии:
    0
    Всем спасибо. Ответ на проблему нашёл коллега, спасибо ему за это.

    Почему то после сохранения адрес
    меняется на
    Ответ здесь
    Код (Text):
    1. /* This is an example of returning the primary key from an insert so that you can do inserts on other tables with foreign keys based on that value.  The date is just used to provied semi-unique data to be inserted.*/
    2.  
    3. $conn = oci_connect("username", "password")
    4. $stmt = oci_parse($conn, "INSERT INTO test (test_msg) values (:data) RETURN test_id INTO :RV");
    5. $data = date("d-M-Y H:i:s");
    6. oci_bind_by_name($stmt, ":RV", $rv, -1, SQLT_INT);
    7. oci_bind_by_name($stmt, ":data", $data, 24);
    8. oci_execute($stmt);
    9. print $rv;
    Я правда не проверял эту реализацию под PDO, но думаю проблем не будет.
     
  10. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.105
    Симпатии:
    1.243
    Адрес:
    там-сям
    вот и хорошо. а в PDO для входящих параметров подходит bindValue() а для возвращаемых bindParam()
    http://www.php.ru/manual/pdostatement.bindparam.html

    offtopic: да уж, сдешний парсер bbcode делает всё, чтобы испортить ссылки на оригинальный мануал )))
     
  11. denisKa

    denisKa Активный пользователь

    С нами с:
    4 сен 2007
    Сообщения:
    46
    Симпатии:
    0
    Спасибо
     
  12. denisKa

    denisKa Активный пользователь

    С нами с:
    4 сен 2007
    Сообщения:
    46
    Симпатии:
    0
    Решил всё таки поставленную задачу средствами PDO. Ну и кому-то это может быть полезным.

    Код (Text):
    1. $sth = $dbh->prepare('INSERT INTO users (first_name, last_name)
    2.                       VALUES (:first_name, :last_name)
    3.                       RETURN id INTO :newID');
    4. $sth->bindValue(':first_name', $first_name, PDO::PARAM_STR);
    5. $sth->bindValue(':last_name', $last_name, PDO::PARAM_STR);
    6.  
    7. // Указываем что $id – это параметр INOUT для хранимой процедуры
    8. // 10 - это длина типа данных
    9. // Чтобы указать, что $id это параметр OUT хранимой процедуры необходимо явно задать длину!
    10. $sth->bindParam(':newID', $id, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, 10);
    11.        
    12. $sth->execute();
    13.        
    14. echo $id;