2012-08-12 202 views
2

我在我的SQL数据库项目中有一个后期部署脚本,它注册了应该是数据库一部分的默认值。我希望这个脚本能够在不改变结果的情况下多次运行,所以如果我需要添加一点修改,我可以手动运行它。SQL幂等

INSERT INTO [UserRole] ([Name]) 
SELECT 'Regular' 
UNION ALL 
SELECT 'Admin' 

INSERT INTO [UserRight] ([Name]) 
SELECT 'CanAccessApplicationLogs' 
UNION ALL 
SELECT 'CanAccessApplicationJobs' 

INSERT INTO [UserRoleRight] ([UserRoleId], [UserRightId]) 
SELECT [Ro].[Id], [Ri].[Id] FROM [UserRight] Ri, [UserRole] Ro 
WHERE ([Ro].[Name] = 'Admin' AND 
     [Ri].[Name] = 'CanAccessApplicationLogs') 
    OR ([Ro].[Name] = 'Admin' AND 
     [Ri].[Name] = 'CanAccessApplicationJobs') 

我怀疑绩效永远不会是问题,因为这个脚本只是插入角色和权利。那么最干净的方法是检查每行是否存在,并只插入那些不在表中的那些?

回答

3

将每个插入包装在IF语句中都可以工作。不知道它是否是最干净的方式。

所以,你的第一个INSERT将成为:

IF NOT EXISTS(SELECT * FROM UserRole WHERE Name = 'Regular') 
BEGIN 
    INSERT INTO [UserRole] ([Name]) 
    SELECT 'Regular' 
    UNION ALL 
    SELECT 'Admin' 
END 
3

一个MERGE可以有很多更清洁,将分别检查每一行,而不IF语句需要每个人身边。

http://coding.abel.nu/2012/08/idempotent-db-update-scripts/有一个很好的例子

+0

这很酷!看起来它甚至可以容纳你删除的条目。我的MySQL有点生疏,所以我需要弄清楚如何概括这个。 – sdanzig 2014-12-07 16:02:07

+0

等一下,不,这不是MySQL。重复密钥我认为是要走的路。没有适应我删除的条目我想。 – sdanzig 2014-12-07 16:20:36