Подтвердить что ты не робот

Повторно запускаемые сценарии 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] 
4b9b3361

Ответ 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) сценариев.