MySQL - INSERT MULTIPLE ROWS - вернуть ID вставленных записей

StalkerClasses

Новичок
Можно ли как-то получить список ID-вставленных записей когда происходит вставка множества записей 1 запросом?
Единственное что нашел по этому вопросу толковое это этот пост:


Но смущает а если в других скриптах идет вставка?
То достоверность вставленных ID уже будет под вопросом?

Нашел еще функции которые связаны с блокировкой таблиц:
Но не пойму их назначение и могут ли они как-то помочь?
PHP:
// "shared lock"
DB::table('comments')->where('post_id', $post_id)->sharedLock()->get();

// "lock for update"
DB::table('comments')->where('post_id', $post_id)->lockForUpdate()->get();
 

Фанат

oncle terrible
Команда форума
Очевидно, что если вот прям так надо получить ид вставленных записей, то не использовать множественную, а вставлять по одной
 

StalkerClasses

Новичок
Сессии разные (не путать с $_SESSION)
Очевидно, что если вот прям так надо получить ид вставленных записей, то не использовать множественную, а вставлять по одной
Просто не пойму есть смысл делать так как в этом примере? Это 100% достоверность вставленных ID?
Или лучше по одной?
 

Valick

Новичок
Очевидно, что если вот прям так надо получить ид вставленных записей, то не использовать множественную, а вставлять по одной
Вставлять нужно столько сколько нужно (естественно с учётом ограничения MySQL)
я ТС уже советовал книжек почитать.
 

MiksIr

miksir@home:~$
Для InnoDB (и только для него) для простых мульти-инсертов, в которых однозначно понятно число строк и нет вставок значений в автоинкремент поле - id будут выдаваться последовательно, ибо резервируются сразу как только начинается исполняться insert.
А вот для различных INSERT ... SELECT - все не так однозначно и зависит от настройки mysql (а дефолтом - от версии mysql)
 

Yoskaldyr

"Спамер"
Партнер клуба
@StalkerClasses Может я чего-то не понимаю, но почему нельзя вставлять по одной записи и после каждого инсерта брать last_instert_id? Если так сильно переживаешь насчет производительности - заверни в транзакцию.
И если честно не могу понять вопрос - что значит достоверность вставленных ID?
 

StalkerClasses

Новичок
PHP:
    // Создать запись (несколько записей)
    public static function recInsertMultiple($data = []){
        $class = get_called_class();
        
        #$filter = [];
        #$filter['selectRaw'] = ' MAX(uid) as before_max_id ';
        #$filter['withoutGlobalScopes'] = true;
        #$before_max_id = self::recSelect('first',$filter);
        
        #$result = $class::getModel()->insert($data);
        
        #$filter = [];
        #$filter['selectRaw'] = ' MAX(uid) as after_max_id ';
        #$filter['withoutGlobalScopes'] = true;
        #$after_max_id = self::recSelect('first',$filter);
        
        #if($result == 1){
        #    $uidList = [];
        #    $filter = [];
        #    $filter['select'] = 'uid';
        #    $filter['where.Ar'] = [];
        #    $filter['where.Ar'][]  = ['uid','>',$before_max_id];
        #    $filter['where.Ar'][]  = ['uid','<=',$after_max_id];
        #    $filter['withoutGlobalScopes'] = true;
        #    $rows = self::recSelect('get',$filter);
        #    foreach($rows as $k => $v){
        #        $uidList[] = $v['uid'];
        #    }
        #    if(count($uidList)>0){
        #        return $uidList;
        #    }
        #    return 0;
        #}
        
        #return 0;
        
        if(count($data)>0 && !empty($data)){
            $filter = [];
            $filter['selectRaw'] = ' MAX(uid) as after_max_id ';
            $filter['withoutGlobalScopes'] = true;
            $after_max_id = self::recSelect('first',$filter);
            $after_max_id = $after_max_id['after_max_id'];
            
            $strForHash = serialize($data).$after_max_id.rand(1,1000000).microtime();
            $keyNumHash = intval(BaseUtility::numHash($strForHash,8));
            foreach($data as $k => $v){
                $data[$k]['insertuidshash'] = $keyNumHash;
            }
            
            $result = $class::getModel()->insert($data);
            if($result == 1){
                $uidList = [];
                $filter = [];
                $filter['select'] = 'uid';
                $filter['withoutGlobalScopes'] = true;
                $filter['where'] = ['insertuidshash','=',$keyNumHash];
                $rows = self::recSelect('get',$filter);
                foreach($rows as $k => $v){
                    $uidList[] = $v['uid'];
                }
                if(count($uidList)>0){
                    return $uidList;
                }
            }
        }
        return 0;
    }
Нашел другой способ - можно в каждую вставленную запись InsertMultiple добавить поле HashInsertId.
Но все равно нужно добавить какое-то уникальное значение на тот случай если сделать несколько вызовов подряд "recInsertMultiple". Что можно добавить еще?
$strForHash = serialize($data).$after_max_id.rand(1,1000000).microtime();

PHP:
$data = [];
$data[] = ['title'=>'-New Title-'];
$data[] = ['title'=>'-New Title-'];

$inserUids = Pages::recInsertMultiple($data);
print "<pre>";
print_r($inserUids);
print "</pre>";
$inserUids = Pages::recInsertMultiple($data);
print "<pre>";
print_r($inserUids);
print "</pre>";

exit();
 
Последнее редактирование:

Yoskaldyr

"Спамер"
Партнер клуба
@StalkerClasses Вот скажи что именно ты хочешь сделать? И зачем тебе именно мультиинстерт?
Просто ты всегда умудряешься выбрать самое неправильное решение для своих задач и потом спрашиваешь на форуме как реализовать это решение..

Вот действительно очень мало случаев когда нужен именно один инсерт с вставкой кучей полей с необходимостью получения значения автоинкремента для каждого из них и когда его нельзя заменить на пачку отдельных инсертов в транзакции. И это явно не твой случай.

Я понимаю ты любитель БДСМ решений, но сделай нормально хоть раз. eval, что я подсказал в другой теме - это как раз БДСМ решение.
 
  • Like
Реакции: AmdY

StalkerClasses

Новичок
Я могу отказаться от этого Multiinsert.
Просто так получается если нужно вставить 100 записей будет сто запросов...
 

Yoskaldyr

"Спамер"
Партнер клуба
Можно ли как-то получить список ID-вставленных записей когда происходит вставка множества записей 1 запросом?
Т.е. на этот вопрос может быть только один ответ:
Зачем это понадобилось? Почему такой вопрос возник? И исходя из этого уже тебе могли бы подсказать правильный ответ
 
Сверху