Как управлять исходным кодом SQL? - PullRequest
4 голосов
/ 21 февраля 2009

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

Я использовал один большой текстовый файл, содержащий IF EXIST ... DELETE GO CREATE PROCEDURE ... для всех sprocs, udfs, представлений и всех вставок / обновлений для скриптов конфигурации.

Со временем были добавлены новые звездочки или изменены существующие звездочки.

Самая большая ошибка (насколько мне известно), которую я допустил при создании этого БОЛЬШОГО текстового файла BIG, заключается в использовании кода для новых / измененных sprocs в начале текстового файла. Я, однако, забыл исключить предыдущий код для новых / измененных sprocs. Давайте проиллюстрируем это:

Скажем, мой БОЛЬШОЙ скрипт (версия 1) содержит скрипт для создания sprocs

sp 1
sp 2
sp 3
view 1
view 2

Таблица версий базы данных обновляется до версии 1.

Теперь в sp 2. произошли некоторые изменения. Итак, версия 2 BIG-скрипта теперь:

sp2 --> (newly added)
sp1
sp2
sp3
view 1
view 2

Итак, очевидно, что запуск БОЛЬШОГО скрипта версии 2 не приведет к обновлению моего sp 2.

Я немного опоздал, осознав это с более чем 100 числами звезд.

Исправительное действие:

  1. Я создал структуру папок. Одна подпапка для каждого просмотра / просмотра.

  2. Я просмотрел последнюю версию BIG-скрипта с самого начала и поместил код для всех скриптов в соответствующие папки. Некоторые сценарии повторяются более одного раза в БОЛЬШОМ сценарии. Если для создания конкретного sproc имеется более одного блока кода, я помещаю более раннюю версию в другую подпапку с именем «old» в папке этого sproc. К счастью, я всегда документировал все изменения, которые я сделал для всех sprocs / view и т. Д. - я записываю дату, номер версии и описание изменений, внесенных как комментарий в коде sproc. Это очень помогло мне выяснить последнюю версию кода для sprocs, когда для sproc имеется более одного блока кода.

  3. Я создал пакетный процесс DOS для объединения всех отдельных сценариев для создания моего БОЛЬШОГО сценария. Я попытался использовать .net streamreader / writer, который путается с кодировкой и знаком "£". Так что пока я придерживаюсь пакета DOS.

Есть ли способ улучшить весь процесс? В настоящий момент я пытаюсь документировать версию BIG-скрипта вместе с отдельными версиями sproc. Например, мне нравится иметь некоторый способ документировать

Big Script (version 1) contains
sp 1 version 1
sp 2 version 1
sp 3 version 3
view 1 version 1
view version 1

Big script (version 2) has
sp 1 version 1
sp 2 version 2
sp 3 version 3
view 1 version 1
view 2 version 1

Любые отзывы приветствуются.

Ответы [ 4 ]

3 голосов
/ 21 февраля 2009

Вы смотрели на Visual Studio Team System Database Edition (теперь в версии для разработчиков)?

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

3 голосов
/ 21 февраля 2009

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

Для обновления каждой таблицы, например, мы используем этот шаблон:

if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[MyTable]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
begin

    CREATE TABLE [dbo].[MyTable](
        [ID] [int] NOT NULL ,
        [Name] [varchar](255) NULL 
    ) ON [PRIMARY]

end else begin

    -- MyTable.Name
    IF (SELECT COL_LENGTH('MyTable','Name')) IS NULL BEGIN
        ALTER TABLE MyTable ADD [Name] [varchar](255) NULL 
        PRINT 'MyTable.Name CREATED.'
    END

    --etc

end
1 голос
/ 21 февраля 2009

Когда мне приходилось обрабатывать несколько таблиц SQL, процедур и триггеров, я делал следующее:

  • Все файлы находятся под контролем версий (в то время CVS, но посмотрите на SVN или Bazaar, например)
  • Один файл на объект, названный в честь объекта
  • make-файл с указанием зависимостей между файлами

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

Makefile избегает подхода «большого файла»: вам не нужно выполнять ВСЕ свой код для каждого изменения.

В Windows вы можете скачать "NMAKE.exe" для использования make-файлов

НТН

0 голосов
/ 21 февраля 2009

Пожалуйста, смотрите мой ответ на аналогичный вопрос, который может помочь:

Обновления схемы базы данных

Некоторые дополнительные очки:

Когда мы делаем релиз, например, для Версии 2 мы объединяем вместе все Sprocs с более поздней модификацией, чем предыдущий Релиз.

Мы осторожно добавляем по крайней мере одну пустую строку в конец каждого скрипта Sproc и запускаем каждый скрипт Sproc с комментарием - в противном случае конкатенация может привести к "GOCREATE NextSproc" - что скучно!

Когда мы запускаем составной сценарий, мы иногда обнаруживаем, что у нас возникают конфликты - например, Вызов sub-Sprocs, которые еще не существуют. Мы продублируем код для таких Sprocs внизу скрипта - чтобы они были воссозданы во второй раз - чтобы убедиться, что таблица зависимостей SQL Server верна. (то есть мы разбираемся с этим на этапе QA для выпуска)

Кроме того, мы помещаем оператор разрешений GRANT внизу каждого сценария Sproc, чтобы при удалении / создании SProc мы повторно предоставляли разрешения. Однако, если ваши разрешения выделены для каждого пользователя или по-разному назначены на каждом сервере, то может быть лучше использовать ALTER, а не CREATE - но это проблема, если SProc еще не существует, поэтому лучше всего делать:

IF NOT EXIST ...
    CREATE PROCEDURE MySproc AS SELECT 'STUB'
    GRANT EXECUTE Permissions

и затем этот Stub немедленно заменяется настоящим оператором ALTER Sproc.

...