metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2010-02-01 07:11 pm

Запросы к БД, опечатки и строгая типизация

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

И каждый раз удивляюсь тому, что разработчики СУБД ложат хер на теорию ради экономии на паре символов и псевдолаконичности и что SQL в разных серверах по разному реагирует на ошибки в типах данных.
А вот была бы строгая типизация - большая часть этих запросов ну нихрена бы тайпчекер не прошла.

Кстати, в этом плане полезен Firebird - там разработчики стараются жостко следовать стандартам, вплоть до того, что ломают обратную совместимость при переходе между версиями, если этого требует кошеризация.
Я вот жалею, что у меня почти нет опыта работы с Postgresql и Oracle - было бы очень интересно сравнить подходы на этот счет в разных серверах, а не только Firebird с MSSQL.

[identity profile] guamoka.livejournal.com 2010-02-01 07:37 pm (UTC)(link)
Недавно довелось подменять под Hibernate Oracle на hsqldb, ибо индусы хотели, чтобы было энтерпрайзно, но оно там нафиг не упало. Обнаружилась любопытная (общеизвестная) вещь, что Oracle хранить пустые строки как null (а на проверку на нулл была завязана ветвистая логика) :) Вот тебе и типизация.

[identity profile] http://users.livejournal.com/_windwalker_/ 2010-02-01 08:09 pm (UTC)(link)
на первый взгляд выглядит как bullshit, ибо id в where не определено, и там должен быть search condition, который вычисляется как true, false or unknown.

Которое, в свою очередь вычисляется через предикат:
<predicate> ::=
<comparison predicate>
| <between predicate>
| <in predicate>
| <like predicate>
| <null predicate>
| <quantified comparison predicate>
| <exists predicate>
| <unique predicate>
| <match predicate>
| <overlaps predicate>

Где я никак в упор не вижу id - 1. Т.е. это либо криворукость самописного парсера SQL, либо навороченность админки 1ц, либо навороченность диалекта SQL от MYSQL.


[identity profile] vromanov.livejournal.com 2010-02-01 08:35 pm (UTC)(link)
Для таких кейзов должно заводится ограничение, что пользователь X не может в одном запросе модифицировать (удалять, вставлять, итд) больше чем Y строк. И то гда таких глубых ошибок будет меньше

[identity profile] gds.livejournal.com 2010-02-01 08:47 pm (UTC)(link)
конкретно в оракле -- "id - 1234" не является валидным условием, но не помню сходу, чтобы так ошибался.
и в случаях, когда пишу на pl/sql и нет гарантий того, что update/delete исполнится без промашек в where, вручную проверяю количество задетых строк, типа "assert(sql%rowcount <= 1)". Сложностей мало, но неинформативный ассерт лучше, чем ошибка в логике.
А про то, что в оракле NULL эквивалентен пустой строке -- о да. Уже долго шлю лучи рака яичек тому, кто принял это решение.

[identity profile] ennor.livejournal.com 2010-02-01 08:57 pm (UTC)(link)
Ну че, update без where - классика. Думаю, каждый, кто правил базы ручками, проходил через это :)

А вообще да, выглядит сомнительно. MSSQL такое не пропустит, насколько я помню; более того, там вообще СУБД не указана...

[identity profile] aamonster.livejournal.com 2010-02-02 07:19 am (UTC)(link)
Хороший подход в плане обратной совместимости - кошерная реализация новой версии + адаптер для старой. Но на это никогда нет времени :-(

[identity profile] demon-gloom.livejournal.com 2010-02-02 10:27 am (UTC)(link)
Cинтаксис, даже самый кошерный все не спасет. Нужно просто что бы программа перед выполнением запроса запроса проводила анализ кол-ва строк затрагиваемых изменением, и на основе обьема изменений требовала вводить капчу из того же квери. Самое главное при этом - подсветка слов в запросе разным цветом. И что бы символы -+,= отличались друг от друга цветом.

Типа если у меня в базе миллион строк, а квери затрагивает одну, то пускать без капчи. А если 500 тыщ, то раза два должно спросить.