1. SQL / Говнокод #13032

    −165

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    delete
        from liaison
    where
        type = 'UsersGroup' and
        `group` = 'static_' || (select id from usergroup where name = :grp)

    Час назад вынес этим запросом все связи между группами и юзерами в боевой базе ;)

    P.S. Почему в mysql все дерьмо, работающее совсем не так, как оно работает почти во всех остальных СУБД, включено по умолчанию?

    Запостил: bormand, 22 Мая 2013

    Комментарии (23) RSS

    • Честно говоря, это один из примеров, где я бы воспользовался курсором и динамикой (хоть все знают, что курсор и динамика - зло). Курсор с динамикой сделали бы запрос более наглядным и прозрачным. А игра с конструкциями типа "'static_' || (select id from usergroup where name = :grp)" - опасное дело, особенно в delete.
      Ответить
      • Туплю, можно проще. Что-то вроде:

        delete from l
        from liaison l inner join usergroup u
        on l.group = 'static_' || CAST(u.id as char)
        where
        type = 'UsersGroup' and u.name = :grp

        Простите, не очень силен в мускуле с типами.
        Ответить
        • Фишка в том, что в мускуле || это не конкатенация, как в нормальных СУБД, а какого-то хуя логическое или. Из-за этого мое условие превратилось в delete from liaison where true ;)
          Ответить
          • Да я только в оракле помню || как конкатенацию... и если честно, то использовал бы +. Плюс - он как бы более канониченЪ в сикеле в роли конкатенации. Надо будет глянуть анси стандарт.
            Ответить
            • > в оракле
              Навскидку еще postgres, sqlite, firebird.
              Ответить
              • Таки || по стандарту... MSSQL и мускуль - злобные нарушители :(

                MSSQL Breaks the standard by using the '+' operator instead of '||'.
                Does not automatically cast operands to compatible types. If an operand is NULL, then the result is NULL.

                MySQL Badly breaks the standard by redefining || to mean OR.
                Offers instead a function, CONCAT(string, string), which accepts two or more arguments.

                Automatically casts values into types which can be concatenated. If an operand is NULL, then the result is NULL.
                Ответить
                • Кстати забавный факт - в мускуле есть режим ANSI, в котором || это именно конкатенация. Т.е. он даже сам себе противоречит ;)
                  Ответить
          • А делать конкатенацию функцией CONCAT религия не позволяет?
            Ответить
            • Дык это ман открывать надо... К тому же с PHP+MySQL я довольно редко общаюсь. А эту самодельную админку к системе хотелось привернуть побыстрее. Поэтому и написал от балды первое, что вспомнилось из postgres/sqlite. Поматерился немного, восстановил табличку, и покурив маны заменил на concat.
              Ответить
          • В МуСкуле (тыдыщ): CONCAT(). Плюсы - получите преобразование к флоат, а || - or.
            Ответить
    • После перехода с Нормальных БД™ на mysql (попросили разок помочь с написанием каких-то небольших, но упоротых запросов), у меня появился синдром отменыя наделал огромную кучу косяков, три раза подряд ставил сервер на колени (top показывал, что mysqld потребляет 99.9% всех возможных ресурсов и категорически не хочет дохнуть). А всё - примитивными вещами, которые _логично_ работают в Нормальных БД™.
      У них там явно своя атмосфера.
      Ответить
    • Ну перед тем как выполнять update/delete сначала делают select.
      И вообще ручные правки боевых баз - зло.
      И напоследок старая истина - любой программист хотя бы раз в жизни запускал update/delete без where.
      Ответить
      • > ручные правки боевых баз - зло
        Любые прямые модифицирующие запросы - зло. Правильно разработать пусть даже для одноразового действия соответствующий функционал (скажем, бизнес-операцию), отладить и использовать только так. Никаких редакторов с прямым выполнением.
        В моей практике бывали случаи, когда где-то погроммист из-за копипасты забыл сменить id, а таблицу сменил, отчего удалилось совсем не то. Да тысячи их.
        Ответить
        • > Правильно разработать пусть даже для одноразового действия соответствующий функционал (скажем, бизнес-операцию), отладить и использовать только так.
          Самый прикол в том, что этот код как раз был в функции, которая выполняла операцию "удаление юзера". Я же не настолько проникся духом пхп, чтобы вызывать запросы и исполнять бинарники прямо из главной функции...

          Так что мой фейл совсем не в прямом использовании запросов, а в том, что я отлаживался на боевом сервере ;)
          Ответить
          • Тогда без вариантов, только отладка на кошках.
            Ответить
      • > И вообще ручные правки боевых баз - зло.
        Золотые слова...

        Просто, как всегда, сложились обстоятельства - торопился, хотел быстрее накодить спартанскую но удобную админку, толком не знал диалект mysql, тестовый сервак от этой системы давно заюзали под другие нужды, а развертывать новый было влом... Тем более под рукой был свежий бекап, да и таблички эти кроме меня все равно никто никогда не правил.

        P.S. На самом деле пользователи даже ничего не заметили, т.к. эти таблички читаются только при логине.

        P.P.S. Но согласен, отлаживаться на боевой базе это большой риск, и показатель нуба, коим я и являюсь ;)
        Ответить
        • Ага, вот оно чо! Люди к сладкому быстро привыкают. Обмазались фрйуорками и Нормальными БД™, думать обленились, вот и получают крэш-апликейшн. Логично было бы предположить, что в чужой стране, говорят на совершенно ином диалекте иного языка, это раз. Специалисты с мозолями на жопе, частенько, совершенно не умеют работать молотком (хотя бы иногда), это два. Спасибо, учту это при поиске очередных соискателей.
          Ничего, бывает, просто Луна сегодня не в той фазе
          Ответить
          • > Логично было бы предположить, что в чужой стране, говорят на совершенно ином диалекте иного языка
            Одно дело когда диалект просто отличается от стандарта (ну функций там добавили, операторов новых, какие-то дополнительные кейворды). Другое - когда авторы СУБД намеренно нарушают стандарты, внося свои бессмысленные и беспощадные "фичи". Вспомните, к примеру, что mysql делает, если не все поля лежат в group by и групповых функциях... а теперь назовите мне еще хотя бы одну базу, у которой есть такое поведение.
            Ответить
          • > думать обленились
            > Специалисты с мозолями на жопе
            > совершенно не умеют работать молотком (хотя бы иногда)
            Окай, не буду принимать это как личное оскорбление. Доля правды тут есть. Но только вот очень часто (где-то в 80% случаев) "работать молотком и думать" = "терять время впустую", примерно как драить плац зубной щеткой, или копать котлован совочком.

            Вы естественно никогда ошибок не допускаете, и всегда полностью читаете ман по всем функциям и операторам, которые вы используете в своей работе?
            Ответить
          • А зачем тогда вообще этот ANSI стандарт? Может, ну его, и пусть все вендоры СУБД пишут свой декларативный язык с преферансом и поэтессами?
            Да, нет такой СУБД (из топ 10), которая бы 100% соответствовала стандарту, но мускуль чаще всего разрывает все шаблоны.
            Так что борманд не зря поднимает волну негодования.
            Ответить
            • Мне эта цитата в последнее время все больше и больше нравится:
              I have not increased nor diminished the measure,
              I have not diminished the palm,
              I have not encroached upon fields,
              I have not added to the balance weights,
              I have not tempered with the plumb bob of the balance.

              Это они так в Древнем Египте после смерти перед Ма'aт оправдывались за несоблюдение стандартов. Кто не соблюдал - того в рай не пускали.
              Ответить
            • © "Точность заменяет глупцам мудрость."
              Ответить

    Добавить комментарий