Подтвердите перед удалением / обновлением в SQL Management Studio? - PullRequest
10 голосов
/ 11 ноября 2008

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

Я все время работал над студией mgmt, но не могу найти опцию подтверждения. Я знаю, что другие инструменты для других баз данных есть.

Ответы [ 10 ]

16 голосов
/ 11 ноября 2008

Я бы посоветовал вам всегда сначала написать инструкцию SELECT с предложением WHERE и выполнить ее, чтобы увидеть, какие строки будет удалять ваша команда DELETE. Затем просто выполните DELETE с тем же предложением WHERE. То же самое относится к ОБНОВЛЕНИЯМ.

13 голосов
/ 11 ноября 2008

В разделе Инструменты> Параметры> Выполнение запроса> SQL Server> ANSI вы можете включить опцию Неявные транзакции, что означает, что вам не нужно явно включать команду «Начать транзакцию».

Очевидным недостатком этого является то, что вы можете забыть добавить Commit (или откат) в конце, или, что еще хуже, ваши коллеги по умолчанию добавят Commit в конце каждого скрипта.

Вы можете привести лошадь к воде ...

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

4 голосов
/ 11 ноября 2008

Во-первых, для этого предназначены таблицы аудита. Если вы знаете, кто удалил все записи, вы можете либо ограничить их права доступа к базе данных, либо работать с ними с точки зрения производительности. Последний человек, который сделал это в моем офисе, в настоящее время находится на испытательном сроке. Если она сделает это снова, ее отпустят. Вы несете ответственность, если у вас есть доступ к производственным данным, и обеспечение того, что вы не причиняете вреда, является одним из них. Это проблема производительности, а также техническая проблема. Вы никогда не найдете способа, чтобы люди не совершали глупых ошибок (база данных не может определить, имели ли вы в виду удаление таблицы a или удаление таблицы a, где id = 100, и большинство людей автоматически получит подтверждение). Вы можете попытаться уменьшить их, только убедившись в том, что люди, выполняющие этот код, несут ответственность, и внедрив политики, помогающие им вспомнить, что делать. Сотрудники, которые ведут себя безответственно с вашими данными о работе (особенно после того, как они получили предупреждение) должны быть уволены.

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

Пример удаления со встроенным выбором

delete a
--select a.* from 
from table1 a 
join table 2 b on a.id = b.id
where b.somefield = 'test'

Но даже эти методы не могут предотвратить все человеческие ошибки. Разработчик, который не понимает данные, может запустить select и все же не понять, что он удаляет слишком много записей. Запуск в транзакции может означать, что у вас есть другие проблемы, когда люди забывают зафиксировать или откатить и заблокировать систему. Или люди могут поместить его в транзакцию и все еще нажимать на фиксацию, не думая так же, как они нажимают «Подтвердить» в окне сообщения, если оно есть. Лучшая профилактика - иметь возможность быстро восстанавливаться после подобных ошибок. Восстановление из таблицы журнала аудита обычно происходит быстрее, чем из резервных копий. Кроме того, у вас есть возможность узнать, кто совершил ошибку и какие записи были затронуты (возможно, вы не удалили всю таблицу, но ваше предложение where было неверным и вы удалили несколько неправильных записей.)

По большей части производственные данные не должны изменяться на лету. Вы должны написать сценарий изменения и сначала проверить его на dev. Затем на Prod все, что вам нужно сделать, это запустить скрипт без изменений, а не выделять и запускать маленькие кусочки по одному. Сейчас в реальном мире это не всегда возможно, так как иногда вы исправляете что-то сломанное только на том продукте, который необходимо исправить сейчас (например, когда никто из ваших клиентов не может войти в систему, потому что важные данные были удалены). В таком случае вы не можете себе позволить воспроизвести проблему сначала на dev, а затем написать исправление. Когда у вас возникают проблемы такого типа, вам может потребоваться исправить непосредственно на prod, и у вас должны быть только dbas или аналитики базы данных, или менеджеры конфигурации, или другие лица, которые обычно отвечают за данные на prod, которые делают исправление, а не разработчик. Разработчики вообще не должны иметь доступа к продукту.

4 голосов
/ 11 ноября 2008

Попробуйте использовать BEGIN TRANSACTION перед выполнением оператора DELETE.

Тогда вы можете выбрать COMMIT или ROLLBACK то же самое.

3 голосов
/ 11 ноября 2008

В SSMS 2005 вы можете включить эту опцию в разделе Сервис | Параметры | Выполнение запроса | SQL Server | ANSI ... check SET IMPLICIT_TRANSACTIONS. Это потребует фиксации, чтобы повлиять на запросы обновления / удаления для будущих соединений.

Для текущего запроса перейдите в раздел Query | Query Options | Execution | ANSI и установите этот же флажок.

На этой странице также есть инструкции для SSMS 2000, если это то, что вы используете.

Как отмечали другие, это не устранит первопричину: вставлять COMMIT в конце каждого нового создаваемого вами запроса почти так же легко, как и запускать запрос в начале.

2 голосов
/ 11 ноября 2008

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

Вероятно, единственным решением будет заменить кого-то на кого-то другого ;). В противном случае они всегда найдут обходной путь

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

2 голосов
/ 11 ноября 2008

Вот почему я считаю, что вы должны всегда:

1 Используйте хранимые процедуры, которые проверены в базе данных dev перед развертыванием в рабочей среде

2 Выберите данные перед удалением

3 Разработчики экрана, использующие интервью и оценку эффективности:)

4 Оценка производительности на основе того, сколько таблиц базы данных они удаляют / не удаляют

5 Обрабатывайте производственные данные, как если бы они были ядовитыми и очень боялись

1 голос
/ 11 ноября 2008

Блокировка:

REVOKE удалить права на все ваши таблицы.

Добавьте триггер аудита и таблицу аудита.

Создание параметризованных удаленных SP и предоставление прав на выполнение только по мере необходимости.

1 голос
/ 11 ноября 2008

Наденьте свой лучший Трогдор и Burninate, пока они не научатся вставлять предложение WHERE.

Лучший совет - использовать гадости в базе данных, чтобы использовать транзакции при тестировании. Это имеет большое значение для предотвращения моментов "упс". Предостережение заключается в том, что теперь вы должны сообщить им COMMIT или ROLLBACK, потому что они наверняка заблокируют вашу БД хотя бы один раз.

0 голосов
/ 11 ноября 2008

Разве нет способа предоставить пользователям необходимые результаты без предоставления необработанного доступа к SQL? Если у вас по крайней мере было отдельное поле ввода для «ГДЕ», вы можете по умолчанию установить его на «ГДЕ 1 = 0» или что-то в этом роде.

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

Еще один уродливый вариант - создать триггер для записи всех УДАЛЕНИЙ (возможно, через некоторое минимальное количество записей) в таблицу журнала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...