защитить базу данных от случайного обновления - PullRequest
1 голос
/ 26 января 2012

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

Я только что выполнил запрос на обновление и случайно обновил все мои 30 000+ записей.К счастью, я работал в своей тестовой базе данных.

    //Particular query that I am talking about is this
    update customers set  
    customer_id = 100 // where clause is missing and it will update all records
  1. Мне было интересно, есть ли способ защитить базу данных от такого массового обновления, может быть триггер, который будет вдвое меньше, если обновлениезатрагивает более 500 записей?Есть ли способ защитить базу данных от случайных плохо отформатированных запросов.Тем не менее, я особенно заинтересован в обновлениях.

  2. Я делаю что-то действительно неправильно, когда я использую SQL Script непосредственно на своем производственном сервере.Я новичок и мне нужен совет специалиста.

Ответы [ 5 ]

2 голосов
/ 26 января 2012

Дайте мне адрес (2).Я думаю, что ваше предложение для (1) может помочь, но давайте сначала поговорим о планировании.

Является ли использование сценариев напрямую «действительно неправильным» или нет, зависит от уровня риска.Важна ли эта миссия данных?У вас есть хорошая резервная копия, включая журналы транзакций, чтобы вы могли восстановить данные за минуту до вашей ошибки?Может ли база данных быть недоступной в течение часа, который потребуется для ее восстановления?

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

2 голосов
/ 26 января 2012

Вы, безусловно, можете поместить триггер обновления в таблицу и выдать исключение, если в псевдотестах INSERTED / DELETED есть определенное большое количество строк - это приведет к тому, что любая транзакция попытается откатиться.

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

1 голос
/ 26 января 2012

Как правило, не рекомендуется обновлять доступ к производственной базе данных.Все необходимые обновления должны управляться с использованием хранимых процедур.Таким образом, вам действительно нужно подумать о том, что вы делаете, прежде чем делать это ..

Кроме того, как упоминал @Neville K, транзакции хороши.Вы можете настроить свои хранимые процедуры так, чтобы они отказывались что-либо делать, если транзакция не выполняется, и, если у вас никогда не было коммитов в ваших процессах, вы всегда можете выполнить откат.Тем не менее, как только вы совершите коммит, его игра в любом случае закончится ..

Нет сложного и быстрого способа обойти это, лучшее, что вы можете сделать, - это затруднить себе (и другим!) Провалиться ..

0 голосов
/ 26 января 2012

Ваш запрос должен выглядеть следующим образом.

SET NOCOUNT ON
SET XACT_ABORT ON
Begin Try
    Begin Tran
      //SQL query
    Commit Tran
End Try

Begin Catch
   Rollback Tran
End Catch

Выполнение обработки исключений приведет к откату базы данных к предыдущему состоянию из-за любых ошибок времени выполнения ...

0 голосов
/ 26 января 2012

Рассматривая ваш запрос, я предполагаю, что в вашей таблице «Клиенты» нет первичного ключа с включенным идентификатором для «Customer_Id», поскольку оба эти параметра в таблице, безусловно, остановили бы выполнение этого скрипта.

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

ПРИМЕР

BEGIN TRAN

UPDATE Customer SET Customer_ID = 100

SELECT * FROM Customer

ROLLBACK
--If results look OK comment out ROLLBACK and comment in the line below
--COMMIT
...