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

    −859

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    create table test(
      id integer primary key auto_increment,
      d datetime not null
    );
    
    insert into test(id) values (1);
    
    -- а сейчас я покажу вам особую уличную магию
    select *, d is null, d is not null from test;
    
    select *, d is null, d is not null from test
    where d is not null;
    
    select *, d is null, d is not null from test
    where d is null;  -- WTF?!
    
    select *, d is null, d is not null from test
    where d is not null and d is null; -- WTF?!

    Все 4 select'а выводят одинаковый результат... MySQL такой MySQL...

    P.S. Вставка всякой херни вместо вывода ошибки лечится добавлением STRICT_ALL_TABLES в sql_mode. А вот where с нулевой датой не лечится, видимо, это баг движка.

    Запостил: bormand, 17 Октября 2014

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

    • http://dev.mysql.com/doc/refman/5.0/en/sql-mode.html

      Да тут целая кунсткамера! Оказывается, сейчас мускуль еще более-менее юзабельный... Судя по режимам совместимости раньше было еще хуже...

      From MySQL 5.0.2 on, the precedence of the NOT operator is such that expressions such as NOT a BETWEEN b AND c are parsed as NOT (a BETWEEN b AND c). Before MySQL 5.0.2, the expression is parsed as (NOT a) BETWEEN b AND c.

      Do not perform full checking of dates. Check only that the month is in the range from 1 to 12 and the day is in the range from 1 to 31. This is very convenient for Web applications where you obtain year, month, and day in three different fields and you want to store exactly what the user inserted (without date validation). Before 5.0.2, this was the default MySQL date-handling mode.

      Treat || as a string concatenation operator (same as CONCAT()) rather than as a synonym for OR.
      Ответить
    • > where d is not null and d is null

      Как говорил guest, Шрёдингер, мы нашли твоего кота!
      Ответить
    • ДАВАЙТЕ ФЛУДИТЬ И ТРОЛЛИТЬ! ;)
      Ответить
    • А d VySQL is not или isnot для null'а надо писать?
      Ответить
      • is not, как и везде.
        Ответить
        • Не везде. В Interbase'е было IsNot, а is not null работало как is (not null), что эквивалентно is null :)

          PS: Что-то я нахимичил когда писал вопрос...
          Ответить
          • > В Interbase'е было IsNot
            - Папа, а стандарт SQL существует?
            - Нет сынок, это фантастика.
            Ответить
            • Вообще существует, но мало кто ему следует до конца. Причина честно говоря мне не совсем понятная, но в целом, мне удалось понять Sql, когда я его не знал, прочитав брошюрку на 100-150 страниц, где автор вообще отошел от какой-то конкретной базы данных, и писал по ansi-92. http://troels.arvin.dk/db/rdbms/ тут есть статья, где сравнивают субд на стандарты. Статья не новая, но как говорится каждый дрочит как он хочет, а там описано кто и как это делает по сравнению со стандартами:)
              Ответить
              • > Причина честно говоря мне не совсем понятная
                Да чё тут непонятного - legacy. Либо ломаем совместимость со старым кодом, юзающим нашу базу, либо ломаем совместимость с другими базами (и стандартом). Само собой все мало-мальски взрослые СУБД выбрали первое. И винить их за это нельзя...

                А у мускуля свои тараканы - у них вообще был только нетранзакционный движок. И часть отклонений и извращений унаследованы от него.
                Ответить
    • а еще он дату норовит апдейтить при каждом апдейте
      Ответить
    • Закопать стюардессу.
      Ответить
      • Так ведь это... того... всё равно же откапывать придётся.
        Ответить

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