你们是否跟踪所选源代码控制系统中的存储过程和数据库架构?
进行更改时(添加表,更新存储的proc,如何将更改添加到源代码管理中?
我们在工作中使用SQL Server,并且我已经开始使用darcs进行版本控制,但是我对通用策略以及任何方便的工具感到好奇。
编辑:哇,谢谢大家提出的所有宝贵建议!希望我可以选择多个“接受的答案”!
你们是否跟踪所选源代码控制系统中的存储过程和数据库架构?
进行更改时(添加表,更新存储的proc,如何将更改添加到源代码管理中?
我们在工作中使用SQL Server,并且我已经开始使用darcs进行版本控制,但是我对通用策略以及任何方便的工具感到好奇。
编辑:哇,谢谢大家提出的所有宝贵建议!希望我可以选择多个“接受的答案”!
Answers:
我们选择编写所有内容的脚本,其中包括所有存储过程和模式更改。不需要所见即所得的工具,也不需要花哨的“同步”程序。
模式更改很容易,您所需要做的就是为该版本创建并维护一个文件,包括所有模式和数据更改。这将成为您从版本x到x + 1的转换脚本。然后,您可以针对生产备份运行它,并将其集成到“每日构建”中,以验证其是否正常运行。请注意,不要更改或删除已编写的架构/数据加载sql,这很重要,因为这样可能会破坏以后编写的所有sql。
-- change #1234
ALTER TABLE asdf ADD COLUMN MyNewID INT
GO
-- change #5678
ALTER TABLE asdf DROP COLUMN SomeOtherID
GO
对于存储过程,我们为每个sproc选择一个文件,并且使用drop / create形式。部署时将重新创建所有存储过程。缺点是,如果在源代码控制之外进行更改,则更改将丢失。同时,任何代码都是如此,但是您的DBA'a需要意识到这一点。这确实阻止了团队之外的人对您的存储过程感到厌烦,因为他们的更改会在升级中丢失。
使用Sql Server时,语法如下所示:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[usp_MyProc]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [usp_MyProc]
GO
CREATE PROCEDURE [usp_MyProc]
(
@UserID INT
)
AS
SET NOCOUNT ON
-- stored procedure logic.
SET NOCOUNT OFF
GO
剩下要做的唯一事情就是编写一个实用程序,该程序可以整理所有单个文件,并使用整个更新集(作为一个脚本)创建一个新文件。为此,首先添加架构更改,然后递归目录结构并包括所有存储过程文件。
作为编写所有脚本的好处,您将在读写SQL方面变得更好。您也可以使整个过程更加复杂,但这是如何在没有任何特殊软件的情况下对所有sql进行源代码控制的基本格式。
附录:Rick是正确的,您将失去使用DROP / CREATE的存储过程的权限,因此您可能需要编写另一个脚本来重新启用特定权限。此权限脚本将是最后运行的脚本。我们的经验发现,ALTER和DROP / CREATE语义之间存在更多问题。青年汽车
在Visual Studio中创建一个“数据库项目”以编写和管理您的sQL代码,并使该项目与解决方案的其余部分一起受版本控制。
我同意(并赞成)罗伯特·保尔森的做法。这就是说,您控制着一支具有责任心和纪律性的开发团队,并遵守这种做法。
为了将其“强加”到我的团队中,我们的解决方案至少维护了Visual Studio Team Edition for Database Professionals的一个数据库项目。与解决方案中的其他项目一样,数据库项目也获得版本控制。将数据库中的所有内容分解为可维护的块,使我的团队“自律”成为自然的开发过程。
当然,作为Visual Studio项目,这绝非完美。您会遇到许多奇怪的问题,这些问题可能会让您感到沮丧或困惑。在完成项目之前,需要对项目的工作原理有一定的了解。例子包括
但是对于没有版本化数据库对象实践的团队来说,这是一个好的开始。当然,另一个著名的替代方案是Red Gate的SQL Server产品套件,大多数使用它们的人都认为它们优于Microsoft的产品。
我认为您应该编写一个脚本来自动设置数据库,包括任何存储过程。然后应将此脚本放在源代码管理中。
根据我的经验,结合不同的观点。在Oracle世界中,一切都由“创建” DDL脚本管理。如ahockley所述,每个对象都有一个脚本。如果需要更改对象,则修改其DDL脚本。有一个包装器脚本可调用所有对象脚本,以便您可以将当前数据库构建部署到所需的任何环境。这是为主要核心创建的。
显然,在实时应用程序中,每当您推送需要新列的新构建时,就不会删除该表并重新创建它。您将要做一个ALTER脚本并添加该列。因此,每次需要进行此类更改时,总有两件事要做:1)编写alter DDL和2)更新核心创建DDL以反映更改。两者都进入源代码控制,但是单个alter脚本更多地是瞬时时间点更改,因为它仅用于应用增量。
您还可以使用诸如ERWin之类的工具来更新模型并向前生成DDL,但是我知道大多数DBA都不相信使用建模工具以所需的方式生成脚本。您也可以使用ERWin定期将您的核心DDL脚本反向工程为模型,但这要花很多时间才能使它看起来正确(每次执行时都花时间)。
在Microsoft世界中,我们采用了类似的策略,但是我们使用Red Gate产品来帮助管理脚本和增量。仍将脚本置于源代码管理中。每个对象仍然有一个脚本(表,存储过程等)。首先,某些DBA确实更喜欢使用SQL Server GUI来管理对象而不是使用脚本。但是,这使得随着企业的发展而持续地对其进行管理非常困难。
如果DDL在源代码控制中,则使用任何构建工具(通常是ant)编写部署脚本都是很简单的。
与上面的Robert Paulson相似,我们的组织将数据库保持在源代码控制之下。但是,我们的不同之处在于,我们尝试限制所拥有的脚本数量。
对于任何新项目,都有固定的过程。我们有版本1的架构创建脚本,存储的proc创建脚本以及可能的初始数据加载创建脚本。所有过程都保存在一个公认的大型文件中。如果使用的是企业库,则包括用于记录的创建脚本的副本;如果它是一个使用ASP.NET应用程序框架(身份验证,个性化等)的ASP.NET项目,则我们还将包括该脚本。(我们从Microsoft的工具中生成了它,然后对其进行了调整,直到它可以在不同站点上以可复制的方式工作。这不是很有趣,但是却是宝贵的时间投资。)
我们使用魔术CTRL + F查找所需的proc。:)(如果SQL Management Studio像VS一样具有代码导航功能,我们将非常喜欢。
对于后续版本,我们通常具有upgradeSchema,upgradeProc和/或updateDate脚本。对于架构更新,我们尽可能地更改表,并根据需要创建新表。对于proc更新,我们拖放并创建。
这种方法确实会产生皱纹。生成数据库很容易,并且很容易在当前数据库版本上获得新的数据库。但是,必须谨慎对待DAL生成(我们目前通常使用SubSonic),以确保DB / schema / proc更改与用于访问它们的代码完全同步。但是,在我们的构建路径中是一个生成SubSonic DAL的批处理文件,因此,检出DAL代码,重新运行该批处理文件,然后在架构和/或proc更改时都将其全部检出,这是我们的SOP。(当然,这会触发源构建,将共享的依赖关系更新为适当的DLL ...)
在过去的经验中,我一直以对数据库更改进行源代码控制的方式来控制,对于产品的每个发行版,总是将所有数据库更改写入脚本并存储在我们正在开发的发行版中。适当的构建过程将根据数据库中存储每个“应用程序”当前版本的表,自动将数据库升级到当前版本。然后,我们编写的自定义.net实用程序应用程序将运行并确定数据库的当前版本,并按照脚本前缀编号的顺序针对该数据库运行任何新脚本。然后,我们将运行单元测试以确保一切都很好。
我们将脚本存储在源代码管理中,如下所示(文件夹结构如下):
我对表和存储过程中的当前命名约定有些不满意,因此我的示例几乎没有显示...
[root]
[应用]
[版本]
[脚本]
\ scripts
MyApplication \
1.2.1 \
001.MyTable.Create.sql
002.MyOtherTable.Create.sql
100.dbo.usp.MyTable.GetAllNewStuff.sql
使用将考虑应用程序和版本的Versions表,应用程序将还原每周生产备份,并运行自当前版本以来针对数据库所需的所有脚本。通过使用.net,我们可以轻松地将其打包到事务中,如果发生任何失败,我们将回滚并发送电子邮件,因此我们知道该发行版包含错误的脚本。
因此,所有开发人员都将确保在源代码管理中维护此代码,以便协调发布将确保我们计划针对数据库运行的所有脚本都将成功运行。
这些信息可能比您想要的要多,但是它对我们来说非常有效,并且由于结构原因,很容易让所有开发人员参与进来。
当发布日到来时,运营团队将遵循发布说明,并从源代码管理中拾取脚本,并使用我们在夜间构建过程中使用的.net应用程序对数据库运行程序包,该程序会自动将脚本打包到事务中,因此如果如果发生故障,它将自动回滚,并且不会对数据库造成影响。
在我的公司中,我们倾向于将所有数据库项作为单独的脚本存储在源代码管理中,就像对待单个代码文件一样。首先在数据库中进行所有更新,然后将其迁移到源代码存储库中,以便保留更改历史记录。
第二步,将所有数据库更改都迁移到集成数据库。该集成数据库准确地表示了生产数据库在部署后的外观。我们还有一个质量检查数据库,代表当前的生产状态(或上一次部署)。在Integration数据库中完成所有更改后,我们将使用架构差异工具(Red Gate的SQL Server SQL Diff)来生成一个脚本,该脚本会将所有更改从一个数据库迁移到另一个数据库。
我们发现这是相当有效的,因为它生成了一个脚本,可以与安装程序轻松集成。我们经常遇到的最大问题是,开发人员忘记将其更改迁移到集成中。
我们将存储过程保留在源代码管理中。
我强烈建议在源代码管理中维护架构和存储过程。
保留存储过程的版本,以便在确定有问题时可以回滚它们。
根据您的意思,模式是不太明显的答案。维护在源代码管理中定义表的SQL对于复制环境(prod / dev / user等)非常有用。
我运行一项作业以将其脚本化为正式的目录结构。
以下是从批处理文件调用的VS2005代码(命令行项目),可以正常工作。代码末尾的app.config键。
它基于我在网上找到的其他代码。设置起来有点麻烦,但是一旦您开始工作,它就会很好地工作。
Imports Microsoft.VisualStudio.SourceSafe.Interop
Imports System
Imports System.Configuration
Module Module1
Dim sourcesafeDataBase As String, sourcesafeUserName As String, sourcesafePassword As String, sourcesafeProjectName As String, fileFolderName As String
Sub Main()
If My.Application.CommandLineArgs.Count > 0 Then
GetSetup()
For Each thisOption As String In My.Application.CommandLineArgs
Select Case thisOption.ToUpper
Case "CHECKIN"
DoCheckIn()
Case "CHECKOUT"
DoCheckOut()
Case Else
DisplayUsage()
End Select
Next
Else
DisplayUsage()
End If
End Sub
Sub DisplayUsage()
Console.Write(System.Environment.NewLine + "Usage: SourceSafeUpdater option" + System.Environment.NewLine + _
"CheckIn - Check in ( and adds any new ) files in the directory specified in .config" + System.Environment.NewLine + _
"CheckOut - Check out all files in the directory specified in .config" + System.Environment.NewLine + System.Environment.NewLine)
End Sub
Sub AddNewItems()
Dim db As New VSSDatabase
db.Open(sourcesafeDataBase, sourcesafeUserName, sourcesafePassword)
Dim Proj As VSSItem
Dim Flags As Integer = VSSFlags.VSSFLAG_DELTAYES + VSSFlags.VSSFLAG_RECURSYES + VSSFlags.VSSFLAG_DELNO
Try
Proj = db.VSSItem(sourcesafeProjectName, False)
Proj.Add(fileFolderName, "", Flags)
Catch ex As Exception
If Not ex.Message.ToString.ToLower.IndexOf("already exists") > 0 Then
Console.Write(ex.Message)
End If
End Try
Proj = Nothing
db = Nothing
End Sub
Sub DoCheckIn()
AddNewItems()
Dim db As New VSSDatabase
db.Open(sourcesafeDataBase, sourcesafeUserName, sourcesafePassword)
Dim Proj As VSSItem
Dim Flags As Integer = VSSFlags.VSSFLAG_DELTAYES + VSSFlags.VSSFLAG_UPDUPDATE + VSSFlags.VSSFLAG_FORCEDIRYES + VSSFlags.VSSFLAG_RECURSYES
Proj = db.VSSItem(sourcesafeProjectName, False)
Proj.Checkin("", fileFolderName, Flags)
Dim File As String
For Each File In My.Computer.FileSystem.GetFiles(fileFolderName)
Try
Proj.Add(fileFolderName + File)
Catch ex As Exception
If Not ex.Message.ToString.ToLower.IndexOf("access code") > 0 Then
Console.Write(ex.Message)
End If
End Try
Next
Proj = Nothing
db = Nothing
End Sub
Sub DoCheckOut()
Dim db As New VSSDatabase
db.Open(sourcesafeDataBase, sourcesafeUserName, sourcesafePassword)
Dim Proj As VSSItem
Dim Flags As Integer = VSSFlags.VSSFLAG_REPREPLACE + VSSFlags.VSSFLAG_RECURSYES
Proj = db.VSSItem(sourcesafeProjectName, False)
Proj.Checkout("", fileFolderName, Flags)
Proj = Nothing
db = Nothing
End Sub
Sub GetSetup()
sourcesafeDataBase = ConfigurationManager.AppSettings("sourcesafeDataBase")
sourcesafeUserName = ConfigurationManager.AppSettings("sourcesafeUserName")
sourcesafePassword = ConfigurationManager.AppSettings("sourcesafePassword")
sourcesafeProjectName = ConfigurationManager.AppSettings("sourcesafeProjectName")
fileFolderName = ConfigurationManager.AppSettings("fileFolderName")
End Sub
End Module
<add key="sourcesafeDataBase" value="C:\wherever\srcsafe.ini"/>
<add key="sourcesafeUserName" value="vssautomateuserid"/>
<add key="sourcesafePassword" value="pw"/>
<add key="sourcesafeProjectName" value="$/where/you/want/it"/>
<add key="fileFolderName" value="d:\yourdirstructure"/>
如果您正在寻找简单易用的解决方案,则我们的Sql Historian系统将使用后台进程自动将DDL更改同步到TFS或SVN,这对在数据库上进行更改的任何人都是透明的。以我的经验,最大的问题是使用服务器上所做的更改将代码保留在源代码控制中,这是因为通常您必须依靠人员(甚至是开发人员)来更改他们的工作流程,并记得检查他们的更改。他们已经在服务器上完成了。将负担加到机器上,使每个人的生活变得更加轻松。