Повторно запускаемые сценарии SQL Server
Каковы наилучшие методы обеспечения повторного запуска вашего SQL-запроса без получения ошибок при последующих запусках?
например.
- проверка того, что таблицы не существуют до их создания
- проверка того, что столбцы еще не существуют до создания или переименования
- транзакции с откатом при ошибке
- Если вы удаляете таблицы, которые существуют, прежде чем создавать их заново, сначала отбросьте их зависимости, и не забудьте их воссоздать после
- Использование CREATE ИЛИ ALTER PROCEDURE вместо CREATE PROCEDURE или ALTER PROCEDURE, если ваш аромат SQL поддерживает его
- Поддерживать внутреннюю схему управления версиями, поэтому один и тот же SQL просто не запускается дважды в первую очередь. Таким образом, вы всегда знаете, где находитесь, глядя на номер версии.
-
Экспортируйте существующие данные в операторы INSERT и полностью воссоздайте всю БД с нуля.
-
отбрасывая таблицы перед их созданием (не самая безопасная вещь когда-либо, но будет работать в крайнем случае, если вы знаете, что делаете)
изменить:
Я искал что-то вроде этого:
IF EXISTS ( SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[foo]')
AND OBJECTPROPERTY(object_id, N'IsUserTable') = 1 )
DROP TABLE foo
Используют ли другие утверждения такие, как это или что-то лучше?
изменить:
Мне нравится предложение Jhonny:
IF OBJECT_ID('table_name') IS NOT NULL DROP TABLE table_name
Я делаю это для добавления столбцов:
IF NOT EXISTS ( SELECT *
FROM SYSCOLUMNS sc
WHERE EXISTS ( SELECT id
FROM [dbo].[sysobjects]
WHERE NAME LIKE 'TableName'
AND sc.id = id )
AND sc.name = 'ColumnName' )
ALTER TABLE [dbo].[TableName] ADD [ColumnName]
Ответы
Ответ 1
Я думаю, что самая важная практика обеспечения повторного запуска ваших сценариев - это.... запускать их с тестовой базой данных несколько раз после любых изменений в script. Ошибки, с которыми вы сталкиваетесь, должны определять вашу практику.
ИЗМЕНИТЬ
В ответ на ваше редактирование по синтаксису, в общем, я считаю, что лучше избегать системных таблиц в пользу системных представлений, например.
if exists(Select 1 from information_schema.tables where table_name = 'sometable')
drop sometable
go
if exists(Select 1 from information_schema.routines where
specific_name = 'someproc')
drop someproc
Ответ 2
Чтобы добавить в список:
- Если вы удаляете таблицы, которые существуют, прежде чем создавать их заново, сначала отбросьте их зависимости, и не забудьте их воссоздать после
- Использование
CREATE OR ALTER PROCEDURE
вместо CREATE PROCEDURE
или ALTER PROCEDURE
, если ваш аромат SQL поддерживает его
Но в конечном итоге я бы пошел с одним из следующих:
- Поддерживать внутреннюю схему управления версиями, поэтому один и тот же SQL просто не запускается дважды в первую очередь. Таким образом, вы всегда знаете, где находитесь, глядя на номер версии.
- Экспортировать существующие данные в операторы
INSERT
и полностью воссоздать всю БД с нуля.
Ответ 3
Недавно я нашел регистрацию для существования, которой я не знал, и мне понравилось, потому что она короче
IF OBJECT_ID('table_name') IS NOT NULL DROP TABLE table_name
раньше, я использовал
IF EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'table_name')
DROP TABLE table_name
Что я нашел полезным, потому что он немного более портативный (MySql, Postgres и т.д.), учитывая различия, конечно
Ответ 4
Чтобы упростить задачу, я настраиваю студию управления на script объекты как повторно выполняемые
- Инструменты
- Параметры
- Обозреватель объектов SQL Server
- Сценарии
- Параметры сценария объекта
- Включить, если не существует предложение Истина
Ответ 5
Для сохранения схем просмотрите инструмент миграции. Я думаю, что LiquiBase будет работать на SQL Server.
Ответ 6
Вам также нужно будет проверить внешние ключи на любых таблицах, которые вы можете удалить или воссоздать. Также рассмотрите любые изменения данных, которые вы можете сделать, - удалите строки, прежде чем пытаться вставить второй раз и т.д.
Вы также можете захотеть ввести код для проверки данных перед удалением таблиц в качестве защиты, чтобы вы не отбрасывали ранее используемые таблицы.
Ответ 7
Для оператора SQL-пакета вы можете указать
Это всего лишь FYI, я просто запустил его 10 раз
IF EXISTS ( SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[foo]')
AND OBJECTPROPERTY(object_id, N'IsUserTable') = 1 )
DROP TABLE foo
GO 10 -- run the batch 10 times
Это всего лишь FYI, я просто запустил его 10 раз
Начало цикла цикла
выполнение выполнено 10 раз.
Ответ 8
"IF OBJECT_ID ('table_name', 'U') IS NOT NULL" синтаксис хорош, его также можно использовать для процедур: IF OBJECT_ID ('procname', 'P') НЕ НЕТ ...
... и триггеры, представления и т.д. Вероятно, хорошая практика для указания типа (U для таблицы, P для прога и т.д. не помню точных букв для всех типов), если ваши именованные строки разрешают процедуры и таблицы имеют похожие имена...
Кроме того, хорошей идеей может быть создание ваших собственных процедур, которые меняют таблицы, с обработкой ошибок, соответствующими вашей среде. Например:
- prcTableDrop, Proc для вызова
таблица
- prcTableColumnAdd, Proc для добавления столбца в таблицу
- prcTableColumnRename, вы получаете идею
- prcTableIndexCreate
Такие procs значительно упрощают создание сценариев смены (в том же или другом db) сценариев.
/Б
Ответ 9
Я описал несколько проверок в своем сообщении Условия DDL "ЕСЛИ не существует" , чтобы перезапустить SQL-скрипты