2009-02-21 135 views
4

我负责数据库。 它有大约126个sprocs,大约20个视图,一些UDF。有一些表格可以为我们的各种应用程序保存固定的配置数据。如何管理SQL源代码?

我一直在使用包含IF EXIST ... DELETE GO CREATE PROCEDURE ...的一个大文本文件...用于配置脚本的所有sprocs,udfs,视图和所有插入/更新。

随着时间的推移,新的sprocs被添加,或现有的sprocs被改变。

最大的错误(据我所知)我在创建这个BIG单个文本文件时所做的是在文本文件的开头使用新/更改的sprocs代码。但是,我忘了排除以前的新代码/更改的sprocs代码。让我们说明这一点:

说我的大脚本(1版)包含的脚本来创建存储过程

sp 1 
sp 2 
sp 3 
view 1 
view 2 

的DATABSE的版本表获取与版本更新1.

现在有在SP的某些变化2.因此,最大的脚本的版本2现在是:

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

所以,很显然运行BIG脚本版本2将不会更新我的SP 2

我很晚才意识到这与100多个sprocs。

补救措施:

  1. 我创建了一个文件夹结构。每个sproc/view的一个子文件夹。

  2. 我已经浏览了bgeinning的BIG脚本的最新版本,并将所有脚本的代码放到了相应的文件夹中。一些脚本在BIG脚本中不止一次地重复。如果有多于一个代码块用于创建特定的存储过程,我会将该早期版本放入另一个称为“旧”的子文件夹中。幸运的是,我总是记录了我对所有sprocs/view等所做的所有更改 - 我记下了日期,版本号以及作为备注存储在代码中的更改的描述。当存在多个代码块时,这帮助我了解了sprocs的最新版本代码。

  3. 我创建了一个DOS批处理过程来连接所有单独的脚本来创建我的BIG脚本。我曾尝试使用.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 

欢迎任何反馈意见。

+0

你为什么还要继续与大脚本斗争?使用Big Script创建什么价值?为什么大脚本如此重要?请更新您的问题,为大脚本提供一些理由。 – 2009-02-22 19:53:03

+0

当我开始时,我有一个BIG脚本和数据库。该公司正在为最新的客户提供最新的数据库,以及BIG脚本来让客户更新他们的旧数据库。 如果有更好的方法来帮助我摆脱这个BIG脚本,我肯定会这样做。 – ahmjt 2009-02-25 22:55:46

回答

3

你看着Visual Studio Team System Database Edition(现在折叠成开发版)?

它会做的一件事是允许维护SQL来构建整个数据库,然后仅应用更改以将目标更新为新状态。我相信,在给定参考数据库的情况下,它还会创建一个脚本,以使数据库与参考模式匹配直至当前模型(例如,在没有开发人员访问产品的情况下部署到生产环境)。

3

我们这样做的方式是为表,存储过程,视图等分开文件,并将它们存储在自己的目录中。为了执行,我们只需要一个执行所有文件的脚本。它比一个巨大的文件更容易阅读。

要更新例如每个表中,我们使用这个模板:

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 
+0

我猜,用来执行所有文件的脚本要求您在安装过程中提供完整的文件夹结构。如果客户端需要数据库升级,您是否将脚本和文件夹结构发送给他们? 我们使用if exists ... from information.schema.tables/routines BTW。 – ahmjt 2009-02-21 12:32:01

+0

如何对要执行的文件的顺序进行排序,尤其是在外键约束和SP依赖于不同表的情况下。 – Joe 2009-02-21 17:57:29

1

当我不得不处理SQL表,过程极少数,并触发我做了以下内容:

  • 所有文件版本控制(CVS在那个时候,但看SVN或集市为例)每个对象
  • 一个文件对象
  • 一个makefile陈述DEPE得名文件之间的差异

这是一个oracle项目,每次更改表格时都必须重新引发其触发器。 而我的触发器使用了几个模块,因此当它们的相关模块更新时也必须重新编译...

makefile避免了“大文件”方法:您不必为每次更改都执行所有代码。

在窗口中,您可以下载 “NMAKE.EXE” 使用的makefile

HTH

-1

请参阅我的回答类似的问题,这可能有助于:

Database schema updates

一些附加分:

当我们做一个版本,例如对于版本2,我们将修改日期的所有Sprocs连接在一起,这些日期比以前的版本更新。

我们注意在每个Sproc脚本的底部添加至少一个空行,并且用注释启动每个Sproc脚本 - 否则连接可能会产生“GOCREATE NextSproc” - 这是一个缺陷!

当我们运行连接脚本时,我们有时会发现我们发生冲突 - 例如,调用不存在的子Sprocs。我们在脚本的底部复制这些Sprocs的代码 - 以便第二次重新创建它们以确保SQL Server的依赖关系表是正确的。 (即我们在发布的QA阶段对此进行分类)

另外,我们在每个Sproc脚本的底部放置了一个GRANT权限语句,以便在我们删除/创建SProc时重新授予权限。但是,如果您的权限分配给每个用户,或者在每个服务器上分配的权限不同,那么最好使用ALTER而不是CREATE - 但如果SProc尚不存在,则会出现问题,因此最好请执行以下操作:

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

然后该Stub立即被真正的ALTER Sproc语句替换。