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

    0

    1. 1
    UPDATE `xxx` SET `updated_count` = (UPDATE `yyy` SET `zzz` = 0 WHERE `zzz` = 42)

    Минимальный код в моей проблеме. Проблема в том, что UPDATE должен возвращать число изменённых строк, а MYSQL говорит, что тут ошибка. Что же мне теперь делать?

    Запостил: d_fomenok, 16 Октября 2017

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

    • апдейт не селект - что он может возвращать? по крайней мере так оно было в старые времена: кол-во апдейтнутых строк было сайд-эффектом апдейта, но не его возвратом (т.е. делалось в два запроса). потому что апдейт не селект - он не возвращает строки значений.
      Ответить
      • UPDATE в MYSQL возвращает количество изменённых строк. Но в MYSQL в подзапросах нельзя использовать ничего, кроме SELECT:
        https://dev.mysql.com/doc/refman/5.5/en/subqueries.html
        Ответить
        • а где можно?
          Ответить
          • В отдельном запросе, а результат получать через API. Если мы, например, вызываем SQL из PHP, то делаем отдельный запрос:
            $cnt = mysqli_query($link, 'UPDATE `yyy` SET `zzz` = 0 WHERE `zzz` = 42');

            А потом в следующем запросе используем полученное значение $cnt.
            Ответить
            • я это и имел в виду когда говорил "сайд-эффект". и к скл он не имеет отношения - это фича софта базы, но не языка.

              я не спец по скл, но я ни в одной базе не видел что бы апдейт (как скл стмт) что то возвращал. возвращать - в скл смысле слова - умеет только селект.

              и как следствие в подзапросе может быть только селект. почему и спрашивал - а в каких диалектах скл апдейт умеет что либо возвращать?
              Ответить
          • Т. е. получается, что для самого языка UPDATE не возвращает ничего, а для внешнего API возвращает количество изменённых строк.
            Ответить
            • Да и в API (родном, няшном) походу ничо не возвращает.
              Сначала нада mysql_query, а затем mysql_affected_rows.

              Так что возврат прикрутили ради пыховцев, чтобы им меньше буков писать было

              https://dev.mysql.com/doc/refman/5.7/en/mysql-query.html
              https://dev.mysql.com/doc/refman/5.7/en/mysql-affected-rows.html
              Ответить
    • Сколько строк в таблице `xxx`?
      Ответить
    • > Что же мне теперь делать?
      2 запроса в транзакции?
      Ответить
      • BEGIN TRANSACTION;
        UPDATE `yyy` SET `zzz` = 0 WHERE `zzz` = 42;
        UPDATE `xxx` SET `updated_count` = ROW_COUNT();
        COMMIT;

        Вот так?
        Ответить
        • Я чувствую, что где-то подвох. Но где?
          Ответить
        • BEGIN TRANSACTION;
          UPDATE `yyy` SET `zzz` = 0 WHERE `zzz` = 42;
          SELECT ROW_COUNT();
          COMMIT;
          Ответить
    • Я вообщде не понимаю зачем делать один запрос.

      У тебя база данных на соседнем континенте, со связью по ISDN, и оплатой за каждый килобайт?
      Ответить
    • ну знаете же про affected rows, ну запрос что ли в гугл не составить, ну

      https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_row-count
      Ответить
      • И, как обычно, одной функции хватит всем. Т. е. использовать её можно только сразу после запроса, изменяющего строки, пока контекст не изменился. Узнаю подход POSIX.
        Ответить
        • да там все граблями обложено. я думаю что триггеры в модерновый мускль уже завезли?

          с другой стороны, эта функция в далёком прошлом была почти уникальна для мускля: по крайней мере сибас и оракакал ничего подобного не предоставляли, потому что апдейт делался от части асинхронно и спекулятивно, и количества строк которые поменялись те базы не считали и с какой либо точностью и не знали.
          Ответить
        • если бы база данных внутри транзакции держала всю статистику по транзакции, она бы охуела
          Ответить
          • а нельзя что-ли к коннекту привязать?

            Инкаус не совсем прав по позикс: глобальный стейт и правда имел место в никсах и сях 70-х, но его уже очень давно отменили
            Ответить

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