Повторно запускаемые сценарии SQL Server - PullRequest
12 голосов
/ 03 апреля 2009

Каковы рекомендации для обеспечения возможности многократного запуска SQL без получения ошибок при последующих запусках?

, например

  • проверка того, что таблицы еще не существуют перед их созданием
  • проверка того, что столбцы еще не существуют перед созданием или переименованием
  • транзакции с откатом при ошибке
  • Если вы отбрасываете таблицы, которые существуют до создания их заново, сначала тоже отбрасывайте их зависимости, и не забудьте заново создать их после
  • Использование CREATE OR 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

Используют ли другие подобные заявления или что-то лучше?

редактирование: Мне нравится предложение Джонни:

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] 

Ответы [ 9 ]

5 голосов
/ 03 апреля 2009

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

EDIT

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

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 
4 голосов
/ 03 апреля 2009

Чтобы упростить задачу, я настраиваю среду управления для сценариев объектов с возможностью повторного запуска

  1. Инструменты
  2. Опции
  3. Обозреватель объектов SQL Server
  4. Scripting
  5. Параметры сценариев объектов
  6. Включить пункт ЕСЛИ НЕ СУЩЕСТВУЕТ Верно
4 голосов
/ 03 апреля 2009

Добавить в список:

  • Если вы отбрасываете таблицы, которые существуют до создания их заново, сначала также отбрасывайте их зависимости, и не забудьте заново создать их после
  • Использование CREATE OR ALTER PROCEDURE вместо CREATE PROCEDURE или ALTER PROCEDURE, если ваш вариант SQL поддерживает его

Но, в конце концов, я бы выбрал одно из следующих:

  • Поддерживать внутреннюю схему управления версиями, поэтому тот же самый SQL просто не запускается дважды в первую очередь . Таким образом, вы всегда будете знать, где находитесь, глядя на номер версии.
  • Экспорт существующих данных в операторы INSERT и полное воссоздание всей БД с нуля.
3 голосов
/ 03 апреля 2009

Я недавно нашла регистрацию на существование, которую я не знала, и она мне понравилась, потому что она короче

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 и т. Д.), Конечно, с учетом различий

0 голосов
/ 19 марта 2012
0 голосов
/ 04 апреля 2009

Синтаксис "IF OBJECT_ID ('table_name', 'U') IS NOT NULL" хорош, его также можно использовать для процедур: ЕСЛИ OBJECT_ID ('procname', 'P') не равен NULL ...

... и триггеры, представления и т. Д. Вероятно, хорошей практикой является указание типа (U для таблицы, P для прог и т. Д. Не помню точные буквы для всех типов) в случае, если ваши цепочки именования разрешают процедуры и таблицы с одинаковыми именами ...

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

  • prcTableDrop, Proc для удаления стол
  • prcTableColumnAdd, Proc для добавления столбца в таблицу
  • prcTableColumnRename, вы поняли идею
  • prcTableIndexCreate

Такие процедуры значительно упрощают создание повторяющихся (в том же или другом БД) сценариев изменения.

/ B

0 голосов
/ 03 апреля 2009

Для пакетного оператора SQL вы можете ввести

Это просто К вашему сведению, я только 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

Это просто К вашему сведению, я только 10 раз пробежал

Начало цикла выполнения партии

выполнение выполнено 10 раз.

0 голосов
/ 03 апреля 2009

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

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

0 голосов
/ 03 апреля 2009

Для поддержки схем, посмотрите на инструмент миграции. Я думаю, что LiquiBase будет работать для SQL Server.

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