На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Akina
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> INSERT INTO ... WHERE
    Имеется таблица foo, типа
    idbar1bar2bar3
    11226ololo
    21227ololo
    31228ololo

    Существует ли такой функционал типа
    INSERT INTO foo (id, bar1, bar2, bar3) VALUES (NULL, 12, 29, 'ololo') WHERE bar1<>12 AND bar2<>29
    Сообщение отредактировано: Gonarh -
      Есть
      ExpandedWrap disabled
        INSERT INTO foo (id, bar1, bar2, bar3) select id, bar1, bar2, bar3
        from foo where bar1<>12 AND bar2<>29

      Есть еще merge но это зависит от диалекта sql.
      Сообщение отредактировано: Bas -
        Ммм, если я правильно понимаю, то будут добавлены уже существующие значения, а мне надо новые, мной указанные. И добавить их в таблицу, если их ещё нет.
          Может проще процедуру написать?

          Добавлено
          Цитата Gonarh @
          а мне надо новые, мной указанные

          Для этого и придумана INSERT INTO ... VALUES , sql не знает что вы хотите добавить данные должны где-то быть. Но проверку перед добавлением можно сделать.
          Сообщение отредактировано: Bas -
            Мне нужно было просто знать, позволяет ли язык такое или нет, буду пилить проверку в другом месте. Спасибо. Тему закрываю.
              Цитата Gonarh @
              позволяет ли язык такое или нет

              нет.
                Цитата Gonarh @
                Имеется таблица foo, типа
                idbar1bar2bar3
                11226ololo
                21227ololo
                31228ololo

                Существует ли такой функционал типа
                INSERT INTO foo (id, bar1, bar2, bar3) VALUES (NULL, 12, 29, 'ololo') WHERE bar1<>12 AND bar2<>29

                сначало проверить через SELECT а потом добавлять или не добавлять через INSERT, так делают правильные чуваки такие как я :D
                Сообщение отредактировано: Cfon -
                  Цитата Gonarh @
                  Существует ли такой функционал типа
                  INSERT INTO foo (id, bar1, bar2, bar3) VALUES (NULL, 12, 29, 'ololo') WHERE bar1<>12 AND bar2<>29

                  Синтаксис INSERT .. VALUES в принципе не предусматривает наличия секции WHERE.
                  Цитата Gonarh @
                  будут добавлены уже существующие значения, а мне надо новые, мной указанные. И добавить их в таблицу, если их ещё нет.

                  Этими проблемами должен заниматься не запрос, а подсистема контроля. Для работы которой создаётся уникальный индекс по полю, совокупности полей либо ограчение (constraint) по выражению, не позволяющие вставить в таблицу дубликат существующей записи. Либо, если индекс не оправдывается по каким-то соображениям, создаются костыли - в простейшем варианте триггеры, в более сложном логика выносится в хранимые процедуры. Однако следует понимать, что при использовании таких костылей всегда есть обходные пути, позволяющие внести в таблицу противоречащие логике данные.
                  Цитата Cfon @
                  сначало проверить через SELECT а потом добавлять или не добавлять через INSERT, так делают правильные чуваки

                  Правильные - используют для этого встроенные средства альтернативной обработки в случае нарушения требования уникальности, которые есть практически в любом диалекте. Merge, Insert .. on Duplicate Key Update и т.п. А делать руками то, что умеет сервер (и умеет, кстати, лучше, чем клиент)... ну костыль он костыль и есть, сиди, трясись и жди, когда сломается.
                  Сообщение отредактировано: Akina -
                    Цитата Akina @
                    Для работы которой создаётся уникальный индекс по совокупности полей не позволяющий вставить в таблицу дубликат существующей записи

                    О, спасибо, не подумал.
                      ну и сиди там с альтернативой, а я буду правильно делать! :D

                      диалект мля :D
                      Сообщение отредактировано: Cfon -
                        Индексы! Гениально!

                        ExpandedWrap disabled
                           INSERT INTO `ololo`.`foo` (
                          `id` ,
                          `bar3` ,
                          `bar2` ,
                          `bar1`
                          )
                          VALUES (
                          NULL , NULL , '2', '2'
                          )
                           
                          Ответ MySQL: Документация
                          #1062 - Duplicate entry '2-2' for key 'test'


                        Сколько же у меня говнокода можно убрать :rolleyes:

                        Добавлено
                        Цитата Cfon @
                        сначало проверить через SELECT а потом добавлять или не добавлять через INSERT, так делают правильные чуваки такие как я :D

                        Я добавляю блоками по 20-30к записей, это чо, мне столько селектов делать? Ебанулся?
                          Цитата Gonarh @
                          cуществует ли такой функционал типа
                          INSERT INTO foo (id, bar1, bar2, bar3) VALUES (NULL, 12, 29, 'ololo') WHERE bar1<>12 AND bar2<>29
                          Сообщение отредактировано: Gonarh - Сегодня, 07:37


                          insert into ...... where not exists(select 1 from foo where bar1 = 12 and bar2 = 29)

                          Добавлено
                          Цитата Gonarh @
                          Индексы! Гениально!

                          Индекс нужен обязательно, но лучше бы, чтоб insert не выдавал ошибок без необходимости
                            Цитата Gonarh @
                            Я добавляю блоками по 20-30к записей

                            Учти, что при нарушении требования уникальности хотя бы для одной записи ни одна запись не будет вставлена - в т.ч. и те, которые требования уникальности не нарушают. Чтобы не-дубликаты вставились, нужно использовать merge-варианты запроса на добавление. Для MySQL это обычно дополнительная секция
                            ExpandedWrap disabled
                              INSERT INTO ...
                              VALUES ...
                              ON DUPLICATE KEY UPDATE id = id;
                            где id - любое (желательно NOT NULL) поле таблицы.
                            В таком варианте все не-дубликаты вставляются, а дубликаты просто игнорируются (поскольку изменения данных не происходит, секция отрабатывается формально и не приводит к реальному обновлению данных теми же значениями).
                            Можно, конечно, использовать и упрощённую версию - INSERT IGNORE, но на последних версиях она может вступать в противоречие с текущими настройками сервера, что заставит менять настройки соединения, а это нехорошо.
                            Сообщение отредактировано: Akina -
                              Цитата Gonarh @
                              Я добавляю блоками по 20-30к записей, это чо, мне столько селектов делать? Ебанулся?

                              ошалел да? :D

                              Добавлено
                              ща я у ся в демо покажу как надо инсертить! :D
                                Цитата Олег М @
                                insert into ...... where not exists

                                Оно, конечно, тоже вариант... но когда формальных ограничений (уникальных индексов) несколько, запрос начнёт пухнуть. Причём быстро - ведь ту же совокупность параметров придётся указывать литерально и в INSERT, и в каждом NOT EXISTS (или в каждом его WHERE). Ну и опять же - дополнительный, в общем ненужный, запрос. Да и обновление пойдёт фиг знает в каком порядке, поскольку все списки - и существующих записей, и добавляемых,- пересортируются для эффективного выполнения предыдущих этапов...
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0499 ]   [ 16 queries used ]   [ Generated: 28.03.24, 23:53 GMT ]