Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Как грамотно получить last_insert_id
 
 автор: Vitaleks   (01.08.2013 в 19:05)   письмо автору
 
 

Доброго времени суток :)
Имеются два запроса, использую mysqli->multi_query

            INSERT INTO Works
            (WorkTitle, WorkDesc)
            VALUES("'.$title.'","'.$desc.'");       
     
            INSERT INTO WorkHistory
            (Time, UserID, WorkID)
            VALUES("'.time().'","'.$user['ID'].'", last_insert_id())


Для дальнейшей работы необходимо получить last_insert_id();

Можно конечно использовать $mysqli->insert_id; , однако получается два запроса к бд, вместо одного, ибо нужный айди можно будет получить только после первого инсерта.

Есть ли возможность выводить из БД Set'ы? Может у кого-то есть реализации этой простой задачки :)

  Ответить  
 
 автор: Sfinks   (01.08.2013 в 19:56)   письмо автору
 
   для: Vitaleks   (01.08.2013 в 19:05)
 

Да вроде и так должно сработать....

Или "Для дальнейшей работы необходимо получить last_insert_id();" нужно понимать, как:
Необходимо получить insert_id от первого запроса?

  Ответить  
 
 автор: Vitaleks   (01.08.2013 в 23:10)   письмо автору
 
   для: Sfinks   (01.08.2013 в 19:56)
 

Да, из 1 запроса. Далее ID необходим в исполнении PHP скрипта.

  Ответить  
 
 автор: Sfinks   (01.08.2013 в 23:17)   письмо автору
 
   для: Vitaleks   (01.08.2013 в 23:10)
 

Тогда только двумя запросами.

  Ответить  
 
 автор: Vitaleks   (01.08.2013 в 23:37)   письмо автору
 
   для: Sfinks   (01.08.2013 в 23:17)
 

Т.е двумя? Отдельным, т.е 3, узнавать айди? Или... ?)

  Ответить  
 
 автор: Sfinks   (02.08.2013 в 08:25)   письмо автору
 
   для: Vitaleks   (01.08.2013 в 23:37)
 

Т.е.
не mysqli->multi_query,
а mysqli->query(запрос №1), узнаете insert_id, затем mysqli->query(запрос №2)

P.S. И НЕ НАДО НИКАКОГО SELECT

  Ответить  
 
 автор: Vitaleks   (02.08.2013 в 13:28)   письмо автору
 
   для: Sfinks   (02.08.2013 в 08:25)
 

Да, я рассматривал такой вариант, минус - два отдельных запроса... Хотелось бы обойтись одним :)
Если запросов на всю генерацию сократить скажем с 15 до 5, в скорости в генерации будет выиграна все же не мало... Да еще и база данных может находится на отдельном сервере, не localhost, то еще ощутимее :D

P.S не просто так же придумали multi_query... Чтож, удаляюсь в изучение доков :)

  Ответить  
 
 автор: Valick   (02.08.2013 в 14:39)   письмо автору
 
   для: Vitaleks   (02.08.2013 в 13:28)
 

не просто так же придумали multi_query..
мне кажется сним еще надо разобраться в каких случаях он оптимальнее, а не пихать его куда не попадя :)

  Ответить  
 
 автор: Sfinks   (02.08.2013 в 20:40)   письмо автору
 
   для: Vitaleks   (02.08.2013 в 13:28)
 

> не просто так же придумали multi_query
Может и не просто... Посмотрите функции:
mysqli_use_result() - Initiate a result set retrieval
mysqli_store_result() - Transfers a result set from the last query
mysqli_next_result() - Prepare next result from multi_query
mysqli_more_results() - Check if there are any more query results from a multi query
Но подозреваю, что mylti_query - не более чем пхп-обертка для просто query, которая поочередно выполняет все запросы.
Но утверждать не буду.

> Если запросов на всю генерацию сократить скажем с 15 до 5
А где это тут у вас генерация, хотелось бы знать?

> в скорости в генерации будет выиграна все же не мало
Никакого в данном случае выигрыша нет. Это все те же 2 запроса! 2 отдельных запроса с двумя перестроениями индексов в двух таблицах. Если бы вы заменили 20 однострочных инсертов к одной и той же таблице одним многострочным - тут да - выигрыш был бы ощутимый. Но не в этом случае.

> Да еще и база данных может находится на отдельном сервере
Если вы хотите гарантированно выполнить одно обращение к серверу, то напишите хранимую процедуру, которая будет принимать 4 значения, использовать их для вставки в 2 таблицы и возвращать insert_id первой вставки... Тогда у вас вообще красивый запрос будет:
CALL mySuperProc("'.$title.'","'.$desc.'","'.time().'","'.$user['ID'].'")
=)

  Ответить  
 
 автор: Valick   (03.08.2013 в 00:41)   письмо автору
 
   для: Sfinks   (02.08.2013 в 20:40)
 

Но подозреваю, что mylti_query - не более чем пхп-обертка для просто query, которая поочередно выполняет все запросы.
не :)

  Ответить  
 
 автор: Sfinks   (03.08.2013 в 10:02)   письмо автору
 
   для: Sfinks   (02.08.2013 в 20:40)
 

Кстати, передача в запрос time() - ровно тоже самое, что вызов в запросе UNIX_TIMESTAMP().
Т.е. ваше
INSERT INTO WorkHistory 
(Time, UserID, WorkID) 
VALUES("'.time().'","'.$user['ID'].'", last_insert_id())
и
INSERT INTO WorkHistory 
(Time, UserID, WorkID) 
VALUES(UNIX_TIMESTAMP(),"'.$user['ID'].'", last_insert_id())
одно и то же.

  Ответить  
 
 автор: Pilotka   (18.12.2015 в 12:24)   письмо автору
 
   для: Sfinks   (03.08.2013 в 10:02)
 

Не совсем, например у меня SQL сервер находится в Эстонии а обработчик скрипта во Владивостоке, и мне необходимо указать время местного сервера

  Ответить  
 
 автор: Valick   (18.12.2015 в 13:12)   письмо автору
 
   для: Pilotka   (18.12.2015 в 12:24)
 

и что из этого следует? time() круче?

  Ответить  
 
 автор: Valick   (01.08.2013 в 21:07)   письмо автору
 
   для: Vitaleks   (01.08.2013 в 19:05)
 

все работает (в РНРадмине проверил), только у вас ошибки синтаксиса во втором запросе, вот и не получается. Да и в структуре БД судя по запросу не так гладко. Например "'.time().'" говорит о том что у вас поле Time (название которого неплохо бы заключить в обратные кавычки `Time`, да и взять это за правило для всех имен полей в запросах) не datetime или timestamp, а какой-нибудь varchar. Тоже самое и с "'.$user['ID'].'" по идее это должно быть число, а пихаете вы его в базу как строку.
            INSERT INTO `Works`
            (`WorkTitle`,` WorkDesc`)
            VALUES("'.$title.'","'.$desc.'");       
     
            INSERT INTO `WorkHistory`
            (`Time`, `UserID`, `WorkID`)
            VALUES(NOW(), $user['ID'], last_insert_id())

где `Time` - это datetime или timestamp
`UserID` - это int
`WorkID` - тоже int

  Ответить  
 
 автор: Vitaleks   (01.08.2013 в 23:07)   письмо автору
 
   для: Valick   (01.08.2013 в 21:07)
 

Может не совсем верно сформулировал саму проблему....
Запрос полностью рабочий, time() - это php функция, использую ее, ибо после меньше геморой с синхронизацией времени на разных машинах.
Проблема немного в другом: мне нужно получить из базы ID новой записи в таблице Works в PHP скрипт. Конечно могу получить скажем сделав запрос типа SELECT, но тогда это уже 3 запроса. Хочется обойтись все же двумя запросами.

Думал насчет такого трюка:

SET @lastID = last_insert_id();


Можно ли как то получить эту переменную из mysql?

  Ответить  
 
 автор: Valick   (02.08.2013 в 00:34)   письмо автору
 
   для: Vitaleks   (01.08.2013 в 23:07)
 

Можно ли как то получить эту переменную из mysql?
угу, сделать SELECT ))))

Запрос полностью рабочий
тогда как я и говорил
в структуре БД судя по запросу не так гладко
хотя с mysqli мало общался, там может стоять защита "от дураков" (не принимайте на свой счет) и принудительное приведение к типу перед занесением в БД

  Ответить  
 
 автор: Vitaleks   (02.08.2013 в 02:26)   письмо автору
 
   для: Valick   (02.08.2013 в 00:34)
 

хотя с mysqli мало общался, там может стоять защита "от дураков" (не принимайте на свой счет) и принудительное приведение к типу перед занесением в БД

mysqli обновленная, дополненная версия прежнего API, мускул тот же...

Проблема не в защите, может такая и есть, пока не выявил...
Вопрос стоял немного в другом, как более изящно взять ID из первого запроса, избегая SELECT :)

Однако, как понимаю, 3 команду - SELECT - придется использовать в любом случае...

  Ответить  
 
 автор: Valick   (02.08.2013 в 14:42)   письмо автору
 
   для: Vitaleks   (02.08.2013 в 02:26)
 

mysqli обновленная, дополненная версия прежнего API, мускул тот же...
ну я как бы не настолько дурак как выгляжу :) mysqli ориентированна на объектный код, процедурка там "вторым эшелоном", так что я бы не назвал это "дополненной версией прежнего API"
драйвер mysqli был написан еще в 2007 году примерно ;)
___
Вопрос стоял немного в другом, как более изящно взять ID из первого запроса
а нафиг он вам нужнет? что вы сним собираетесь дальше делать?

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования