提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|使用教程|编辑:杨鹏连|2020-08-26 11:17:39.613|阅读 286 次
概述:在本文中,我将说明如何使用SQL Compare命令行,同义词和一些独创性来完成所有这些工作。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
SQL Compare是一款比较和同步SQL Server数据库结构的工具。现有超过150,000的数据库管理员、开发人员和测试人员在使用它。当测试本地数据库,暂存或激活远程服务器的数据库时,SQL Compare将分配数据库的过程自动化。
Giorgi Abashidze解释了他的团队如何使用带有SQL Compare命令行和一些SQL同义词的两阶段部署过程来自动为其每个客户进行自定义部署,而只需要在源代码管理中为每个版本维护一个分支。
在我以前的文章中,从使用SQL比较命令行的源代码控制到数据库,我解释了我的团队如何使用SQL比较命令行为我们的客户自动化数据库部署,而无需访问实际的暂存数据库或生产数据库,这是不可能的这是一个银行数据库。我展示了如何通过仅访问我们的开发数据库(包含在TFS源代码管理下),如何使用SQL Compare命令行来部署数据库元数据和所有客户通用的代码。
但是,除了此共享代码外,还必须为我们的每个客户提供每个软件版本的独特变体,以便向他们提供可满足其不同业务和合规性要求的自定义例程。我们每个客户都需要其中一些例程,当然,此专有功能应始终仅部署到该客户的生产数据库中:至关重要的是,任何客户都不能看到专门为另一位客户编写的逻辑。
我们如何实现这一目标?传统的观点似乎是,在每个发行版中,我们将数据库版本的每个特定于客户的变体视为一个单独的分支。但是,这可能会增加构建的复杂性。有了一些创造力,我们可以避免这种情况,而是为每个新版本创建一个分支,我们可以使用该分支来维护和部署我们每个客户的所有共享逻辑,以及专用于无限数量客户的逻辑。
在本文中,我将说明如何使用SQL Compare命令行,同义词和一些独创性来完成所有这些工作。
我们如何将客户特定的例程存储在单个数据库中
因此,为了更接近我们的开发数据库的构建方式,我们假设我们的Trunk结合了我们所有的逻辑。假设我们有三个客户Cust1,Cust2和Cust3。
我们还有一些代码,即SQL存储过程,称为SQL存储过程loan.calculate_effective_rate,该过程根据某种算法来计算在一段时间内对贷款支付的实际利率,称为“有效利率”。对于所有客户来说,这是相同的代码,但是有一天,客户Cust1要求我们更改其版本的算法,这意味着我们现在需要维护和部署“有效率”过程的两个不同版本。
首先,我们需要effective_rate按照Cust1的要求,为该过程实现替代算法(从这里开始,我将使用其名称的这种缩写形式)。我们只有一个开发数据库,称为Trunk,并且由于任何例程中每个例程的名称都必须唯一,这意味着我们必须有一种命名策略来区分这些变体。
我们这样做的方法是:
因此,在这种情况下,我们将创建一个SQL同义词并将其部署到每个客户,该SQL同义词具有effective_rate引用该effective_rate_default过程的名称。当然,Cust1仅此同义词必须不引用默认过程,而是引用Cust1变体。但是,正如我已经提到的,我们在源代码管理中仅维护一个数据库,而在Trunk(以及任何发行分支)中,每个同义词始终仅引用相关操作的默认实现。那么我们如何实现这一目标呢?
答案是一个两阶段的部署过程。第一阶段向每个客户部署effective_rate_default过程以及effective_rate引用该过程的同义词。第二阶段仅将过程部署到Cust1 ,然后在Cust1数据库中删除同义词,并创建一个引用的新过程。
effective_rate_cust1effective_rateeffective_rate_cust1
通过遵循这种方法,基于对每个客户的SQL同义词和两阶段部署过程,我们可以在一个开发数据库中包含所需的专用例程,因此仍然可以为我们的客户提供代码,考虑到不同的业务和合规性要求。
让我们看看如何使用SQL Compare命令行实现此两阶段部署过程。
使用SQL比较的2阶段部署
我们将在简化的部署示例中稍作扩展,并假设有三个客户(Cust1,Cust2和Cust3)都需要定制“有效率”算法的变体。
部署过程的第一阶段将生成一个部署脚本,该脚本将交付给每个客户数据库并在每个客户数据库上运行。这将使所有通用数据库例程(即,没有名称以客户别名结尾的任何例程)升级到相同版本。
第二阶段生成零个或多个特定于客户的同步脚本,这些脚本仅创建或更新特定于该客户的SQL例程,这意味着任何例程的名称都以该用户的别名结尾,在这种情况下,cust1,cust2或cust3。它还将删除并重新创建任何同义词,在本例中为effective_rate同义词,以便每个人始终绑定到正确的基础实现。
为了满足这些要求,我们对所需的每个同步脚本执行一次SQL比较命令行。
阶段1:生成常规部署脚本
在部署过程的第一阶段,我们只执行一次SQL Compare CL,并通过提供一个名为“ shared.xml ” 的XML argfile,传入指示其比较哪些数据库以及如何进行比较的所有参数:
“%programfiles(x86)%\ Red Gate \ SQL Compare 13 \ sqlcompare” /Argfile:"shared.xml“我在上一篇文章中解释了此Argfile的基本内容,但重要的一点是,首先,它是直接从源代码控制位置比较数据库的两个即时点版本,即新版本和先前版本。 ,其次包括对相应过滤器文件(shared.scpf)的引用。此过滤器文件使用如下所示的过滤器表达式排除任何特定于客户的模式对象版本(在这种情况下,任何以Cust1,Cust2或Cust3结尾的版本):
(@NAME NOT LIKE '%[_]cust1') AND (@NAME NOT LIKE '%[_]cust2') AND (@NAME NOT LIKE '%[_]cust3')当然,如果您的客户别名全部遵循标准模式(如本简化示例中的做法),则可以使用更通用的过滤器,例如(@NAME NOT LIKE' %[_]cust[0-9]')。但是,我们所有的真实客户名称都不相同,因此不可能进行这种模式匹配。
结果,SQL Compare将生成一个SQL同步脚本,该脚本将仅创建effective_rate_default存储过程,然后删除该effective_rate同义词,然后重新创建该同义词,以使其引用默认过程(CREATE SYNONYM effective_rate FOR effective_rate_default)。
阶段2:生成客户特定的部署脚本
实际上,对于每个客户,此阶段包括两个部分:
“%programfiles(x86)%\ Red Gate \ SQL比较13 \ sqlcompare” /Argfile:"cust1.xml“ “%programfiles(x86)%\ Red Gate \ SQL比较13 \ sqlcompare” /Argfile:"cust2.xml“ “%programfiles(x86)%\ Red Gate \ SQL比较13 \ sqlcompare” /Argfile:"cust3.xml“每个argfile的内容与shared.xml文件的内容几乎相同,唯一的区别是每个特定于客户的argfile包含对该客户的过滤器文件的引用(例如Cust1.scpf),该引用指示SQL Compare CL使用以下表达式,仅检测特定于该客户的更改
(@NAME LIKE '%[_]cust1')当比较运行时(例如对于Cust1),SQL Compare将生成一个部署脚本,该脚本将创建,修改或删除*_cust1代表Cust1已安装版本的主干分支中的任何对象,因此它将与源代码控制中的最新版本同步。在这种情况下,它将创建effective_rate_cust1存储过程。
但是,SQL Compare为每个客户自动生成的部署脚本不会将当前的effective_rate同义词(通过在阶段1中运行通用脚本创建)替换为引用effective_rate_cust1存储过程的同义词,因为该同义词在Trunk或任何单个分支中对于每个主要版本(v241,v242等),始终引用默认实现。
因此,每次SQL Compare自动生成特定于客户的同步脚本时,我们都需要对其进行修改,以“重置”脚本中的任何同义词,以便它引用相关操作的特定于特定于客户的实现,或者如果不再需要自定义变体,则恢复为默认操作。
我们不能为此使用标准的SQL Compare部署后脚本,首先,因为当直接与源代码控制位置进行比较时,该工具当前不支持使用它们。无论如何,由于我们简单的“每个发布一个分支”策略,我们无法动态地为每个客户生成部署后脚本,也无法更改每个脚本中的同义词以引用正确的客户实现。使其起作用的唯一方法是使用“每个版本的每个客户变体一个分支”的更复杂的构建方案,将每个分支脚本化到一个文件夹中,然后向其中添加一个后部署脚本,以为此重置同义词。
但是,我们更喜欢使用更简单的源代码控制方法,那么我们该怎么做呢?当SQL Compare将特定于客户的同步文件写入我们选择的目录(由该out客户的XML argfile中的参数指定)时,我们将使用一个本地工具将其打开,并在自动生成的代码的末尾添加一行,以执行我们编写的存储过程称为switch_synonyms_to_customer。此过程接受组织的别名的参数(应将同义词绑定到该参数),然后遍历所有SQL同义词,将它们逐个删除,然后使用同义词引用的基础对象的适当名称重新创建它们。默认值或专用例程(如果特定客户需要)。
因此,对于cust1:
EXEC altasoft.switch_synonyms_to_customer @alias = 'cust1'对于cust2:
EXEC altasoft.switch_synonyms_to_customer @alias = 'cust2'等等…
为每个客户运行部署
我们向每个客户提供用于部署所有公共对象的常规部署脚本,并且,如果需要,我们还为每个客户提供为其定制逻辑提供的其他自定义部署脚本,该脚本还将正确重置所有同义词。他们必须始终始终先运行常规脚本,只有完成后才运行其自定义脚本。
结论
如果您正在为许多不同的客户开发数据库应用程序,那么您的客户的需求将开始出现分歧,并且单个部署无法满足您的需求。毕竟,当地的税收和法律以及不同的商业惯例将决定客户如何计算某些财务价值。
为了将所需逻辑中的所有变体仅提供给需要它的客户,SQL Compare命令行可以完成99%的工作。它会生成一个通用同步脚本,以部署每个客户所需的从发行到发行的任何更改,然后针对具有“特殊”要求的每个客户生成单独的同步脚本文件。
通过使用同义词表示每个必需的业务操作,并在每个特定于客户的同步脚本的末尾“手动”重置它们,以便它们始终引用此操作的正确实现,我们避免了对调用者进行任何更改码。
在每个发行版中,都有可能为客户创建了一些新逻辑,或者更新了现有的自定义逻辑或将其删除。如果某些操作不再需要自定义实现,则将其删除,因此客户将返回该操作的默认实现。
相关产品推荐:
SQL Prompt:SQL语法提示工具
SQL Toolbelt:Red Gate产品套包
SQL Monitor:SQL Server监控工具
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:本文探讨 SQL Server 中 NULL 和空值之间的区别,并讨论如何有效地处理它们。
Unity 是一款功能极其丰富的游戏引擎,允许开发人员将各种媒体集成到他们的项目中。但是,它缺少最令人兴奋的功能之一 - 将 Web 内容(例如 HTML、CSS 和 JavaScript)直接渲染到 3D 场景中的纹理上的能力。在本文中,我们将介绍如何使用 DotNetBrowser 在 Unity3D 中将 Web 内容渲染为纹理。
DevExpress v24.2帮助文档正式发布上线了,请按版本按需下载~
本教程将向您展示如何用MyEclipse构建一个Web项目,欢迎下载最新版IDE体验!
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢