За последние 24 часа нас посетили 19946 программистов и 1695 роботов. Сейчас ищут 1685 программистов ...

Узнать ИД записи перед ее созданием

Тема в разделе "MySQL", создана пользователем Алекс8, 23 авг 2017.

  1. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    В общем помогите, а то что то гугл мне ничего не сказал..
    Есть у меня к примеру табличка

    1. ИД - автоинкрементальный столбец
    2. Имя - которое должно быть таким "новое_имя" + ИД, то есть слово плюс текущее значение автоикремента строки..

    Как правильно это сделать?

    1. вариант с select max - не очень правильный.. потому что если добавили новую строку с ИД 5 и удалили ее сразу то следующий автоинкрементный номер будет будет уже 6.. а max выдаст 4 к примеру..
    2. Рассматриваю вариант с добавлением строки а потом сразу update - но мне кажется что это костыль... есть что то более умное?))
    3. Рассматриваю вот такой еще вариант show table status like 'table' - но не знаю насколько он правильный..

    Спасибо)
     
  2. Alesto

    Alesto Новичок

    С нами с:
    15 янв 2017
    Сообщения:
    72
    Симпатии:
    8
    Почему считаешь 2 вариант костылем?
     
  3. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    мне кажется правильно не придумывать какое то случайно ИМЯ а потом его переименовывать.. а сразу давать правильное имя..
     
  4. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.859
    Симпатии:
    749
    Адрес:
    Татарстан
    может не нужно такое имя давать?
    ведь его всегда можно вычислить как CONCAT(name,"_",id) AS new_name

    что 1, что 3 - не гарантируют вставки между этими запросами и вставкой нового элемента
    потому 2 - более верный вариант...
     
  5. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    да тут надо что бы такие имена в базе хранились. . тут получается что происходит авторегистрация, и отображаемое имя будет другое.. а это должно быть как бы служебное что ли))
     
  6. Alesto

    Alesto Новичок

    С нами с:
    15 янв 2017
    Сообщения:
    72
    Симпатии:
    8
    Если хочешь обойтись 1 запросом и иметь "уникальное" служебное имя я бы посоветовал использовать
    PHP:
     
  7. TeslaFeo

    TeslaFeo Старожил

    С нами с:
    9 мар 2016
    Сообщения:
    2.984
    Симпатии:
    759
    в народе сказывают, что шляпа это полная, и костыль дремучий, но вот ссылка где глаголят о реализации сего.

    А вообще, если тебе где-то нужно вывести имя_id то вполне можно сделать так:
    PHP:
    1. echo $row['name'].'_'.$row['id'];
    и не закладывать какулю в админку, которая вдруг сломается при переезде, или типа того.
    --- Добавлено ---
    чем проще, тем надежнее)
     
  8. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Правильно 2-й вариант.
     
  9. Познающий php

    Познающий php Новичок

    С нами с:
    23 мар 2017
    Сообщения:
    381
    Симпатии:
    74
    Все еще не видно аргументов за такую реализацию. ID уникальный сам по себе и есть служебное имя пользователя.
     
  10. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    ну уже поздно аргументировать)) уже все сделал))
     
  11. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    А на уровне движка вариант не подходит?
    PHP:
    1. $mysqli->insert_id;
    PHP:
    1. $pdo->lastInsertId();
     
  12. Abyss

    Abyss Старожил

    С нами с:
    12 дек 2015
    Сообщения:
    1.298
    Симпатии:
    218
    Адрес:
    Default city
    Не подходит, данные операции выдают информацию после добавления в базу. А ОП хочет узнать до.

    @Алекс8 этот подход плох, вообще сам по себе. ID на то и ID. А при вычислении следующего ты можешь выхватить race condition. Попробуй резервировать место. В лучшем случае update, в худшем - кроном выпилишь все тестовые.
     
    Fell-x27 нравится это.
  13. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    записи будут добавлять 2-3 штуки в сутки.. так что врядли поймаю..
    уже сделал по варианту 3.. но вот сейчас переделываю по 2 варианту)
     
  14. retvizan

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

    С нами с:
    27 дек 2013
    Сообщения:
    68
    Симпатии:
    22
    Fell-x27 и Алекс8 нравится это.
  15. Okto

    Okto Новичок

    С нами с:
    19 авг 2017
    Сообщения:
    12
    Симпатии:
    9
    Ради интереса попробовал следующие методы (СУБД MySQL):
    1. Триггер на AFTER INSERT — запрос на создание не выполняется, потому что обновление вставленной строки запрещено
    2. Сделал триггер на BEFORE INSERT
      Код (Text):
      1.  
      2. DROP TRIGGER IF EXISTS trigger1;
      3.  
      4. CREATE TRIGGER trigger1 BEFORE INSERT ON table1
      5. FOR EACH row BEGIN
      6.   SET @auto_id := ( SELECT AUTO_INCREMENT
      7.                     FROM INFORMATION_SCHEMA.TABLES
      8.                     WHERE TABLE_NAME='table1'
      9.                       AND TABLE_SCHEMA=DATABASE() );
      10.   SET new.name= concat(new.name, '_', @auto_id);
      11. END;
      Работает, т.е. обновляет столбец name, но странно:
      Код (Text):
      1. INSERT INTO table1(NAME) VALUES('test'), ('preved'), ('medved');
      Код (Text):
      1. SELECT * FROM table1;
      2. +----+----------+------+
      3. | id | name     | desc |
      4. +----+----------+------+
      5. |  1 | test_1   | NULL |
      6. |  2 | preved_4 | NULL |
      7. |  3 | medved_4 | NULL |
      8. +----+----------+------+
    3. Добавил генерируемый столбец (ссылка):
      Код (Text):
      1. ALTER TABLE table1 ADD COLUMN total_col2 VARCHAR(100) AS (concat(`name`, '_', `id`));
      Работает как нужно:
      Код (Text):
      1.  
      2. TRUNCATE table1;
      3. INSERT INTO table1(NAME) VALUES('test'), ('preved'), ('medved');
      4. SELECT * FROM table1;
      5. +----+----------+------+-----------+------------+
      6. | id | name     | desc | total_col | total_col2 |
      7. +----+----------+------+-----------+------------+
      8. |  1 | test_1   | NULL |         2 | test_1_1   |
      9. |  2 | preved_4 | NULL |         4 | preved_4_2 |
      10. |  3 | medved_4 | NULL |         6 | medved_4_3 |
      11. +----+----------+------+-----------+------------+
      Чехарда с номерами в total_col2 из-за того, что триггер всё ещё работает.
     
  16. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.114
    Симпатии:
    1.244
    Адрес:
    там-сям
    по хорошему, тебе не должно хотеться этого :) но если таки хочется, то вариант с update единственно верный. можешь, кстати, обойтись голым mysql, в нём есть функция last_insert_id()
    Код (Text):
    1. UPDATE table1
    2. SET stringfield = CONCAT('xуйнанэ_', id)
    3. WHERE id = last_insert_id()
    --- Добавлено ---
    если у тебя скрипт гарантированно будет в паре с нужной версией mysql, то да, генерируемый столбец это решение.

    но помоему проще эту хотелку решать в момент выборки данных в SELECT или вообще на стороне PHP при заполнении шаблона ))) то есть не создавать вообще лишнего поля.
     
  17. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Блокировка таблиц, транзакции спасают