Задать вопрос
  • Какие вам дают вопросы на собеседовании?

    @xaphazard
    1) Как уже говорили выше очевидную вещь, задание на собеседовании - это не "сделать кое-как, чтобы работало", а "сделать максимально хорошо, чтобы показать насколько хорошо ты вообще можешь делать эту работу"
    2) В условии сказано "над полями и записями таблицы допускаются любые одиночные и групповые операции". Это значит, что могут, например апдейтом уменьшить количество у части уже давно совершенных операций, или назначить каждой операции новый рандомный склад назначения. И все подобные действия нужно поддерживать. Так что задание, фактически, не выполнено.
    3) Не используйте курсоры и циклы в случае, если можно решить задачу без них. Миллион инсертов по 1 строке в цикле будет работать на порядки дольше чем 1 инсерт миллиона строк. В данном случае задача решается так же без цикла.
    4) А что будет, если в блоке if (@flag_in > 0 and @flag_out > 0) после выполнения первого update второй апдейт упадет с ошибкой (от недостатка памяти на сервере, например)? А что если между двумя апдейтами вклинится другой, от другого запроса? Стоит поботать транзакции и try/catch

    Как бы делал я (ваще не факт, что это идеальное решение):
    1) завернуть все в try блок, в catch откатывать транзакцию на точку в начале блока, если что-то пошло не так.
    2) повесить ограничение на таблицу Размещение, чтобы не позволять отрицательные количества. В случае чего возникнет ошибка при вставке, отрабатывает 1)
    3) В случае удалений-апдейтов - находим все склады, на которые это влияет, заново по Движению пересчитываем для них данные в Размещении. Никаких циклов, 1 запрос. (удаления можно на самом деле оптимизировать, аналогично пункту 4)
    4) В случае вставки можно поступть аналогично, но можно оптимизировать и считать разницу относительно уже обработанного состояния в Размещении. Опять же, никаких циклов.
    5) Заметить работодателю, что в целом постановка задачи не особо корректна: нет времени Движений, поэтому нельзя адекватно обработать ситуацию, например на склад приходило (+10)(-5)(+100), а потом заменили (-5) на (-50). В итоге сумма то на складе положительна, но был момент, когда она была < 0.

    Вообще на вашем месте я бы переписал решение максимально хорошо, просто для повышения своей квалификации. Здесь смогут дать мнение, насколько лучше стало. Плюс поботать try-catch и транзакции. Плюс избавляться от "программистского" стиля в SQL коде - если есть циклы и куча if, значит что-то скорее всего сделано не так.
    Ответ написан
    3 комментария