CRUD或不CRUD

时间:2013-09-12 11:09:23

标签: asp.net sql-server crud

我知道使用CRUD的好处,并且还有some disadvantages,但是我希望获得更多关于将数据写入数据库的过程的专家反馈和建议,特别是关于最佳实践和可能的专业人士和骗子。

作为开发人员,我遇到过两种创建记录的基本方法。第一个(在我见过的大多数作品中通常最没用的)是创建一个存根,并在需要的地方使用各种填充字段(包括PK)。这通常会导致数据库周围出现大量不相关的记录而没有实际用途。

第二种方法是仅在内存中保存存根,为对象的PK字段提供(将会是)默认值,例如-1来表示新记录。这使数据库访问保持最小,特别是如果以后不需要记录。

就个人而言,我发现第二种方式比第一种方式更宽容,更直接。但是,我想提出的问题是,是否要排除CRUD,转而采用基于上述默认值执行CRUD过程的INSERTUPDATE方面的存储过程。价值,像... ...

BEGIN
    IF @record_id = -1 
        INSERT ....
    ELSE
        UPDATE ....
END 

任何反馈都将不胜感激。

1 个答案:

答案 0 :(得分:1)

根据经验,我倾向于写Upsert程序.......但是我基于unique_constraint而不是代理键的“匹配”。

例如。

dbo.Employee EmployeeUUID是PK,代理键 SSN是一个独特的约束。

dbo.uspEmployeeUpsert would look something like this:


Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN )
Select NEWID() , LastName , FirstName , SSN 
from @SomeHolderTable holder
where not exists (select null from dbo.Employee innerRealTable where 
innerRealTable.SSN = holder.SSN )

Update dbo.Employee 
Set EmployeeUUID = holder.EmployeeUUID
, LastName = ISNULL ( holder.LastName , e.LastName ) /* or COALESCE */
, FirstName = COALESCE ( holder.FirstName , e.FirstName )
from dbo.Employee e , @SomeHolderTable holder
Where e.SSN = holder.SSN

您也可以使用MERGE功能。

你也可以用SurrogateKey替换SSN(在这种情况下是EmployeeUUID)

你问的@SomeHolderTable是什么?

我喜欢将xml传递给存储过程,将其粉碎成@Variable或#Temp表,然后为CU编写逻辑。 D(elete)也是可能的,但我通常会分离到一个单独的程序。

为什么我这样做?

因为我可以用一次db命中更新1或100或1000或N条记录。 我的逻辑很少改变,被隔离到一个地方。

现在,粉碎Xml的性能很小。 但我发现99%的时间都可以接受。 每隔一段时间,我就会编写一个非“基于集合”的Upsert例程。但这适用于重击击使用的重击手程序。

这是我的看法。

您可以在本文中看到此方法的“基于集合”部分(使用较旧的OPENXML语法):

http://msdn.microsoft.com/en-us/library/ff647768.aspx

找到短语:“使用OpenXML执行批量更新和插入”

以下是上述网址所涉及的“更多代码”版本:

http://support.microsoft.com/kb/315968

修改

if exists ( select 1 from dbo.Employee e where e.SSN = holder.SSN )
BEGIN

    Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN )
    Select NEWID() , LastName , FirstName , SSN 
    from @SomeHolderTable holder
    where not exists (select null from dbo.Employee innerRealTable where 
    innerRealTable.SSN = holder.SSN )
END

我不一定会这样做。但如果你想要一个“布尔检查”,这是一个选项。

所以,通过我的uniqueidentifier设置,当我知道我有一个新项目时,我会将“空Guid”(00000000-0000-0000-0000-000000000000)(C#中的Guid.Empty)传递给该过程。这将是你的情景中的“-1”检查。

这是一种方法,您可以检查“if exists”。

这有点取决于你手中有多少只手。

另外,我没有提到当我有很多手牌时,我会粉碎xml .....然后我会在我的CU语句中做一个BEGIN TRAN和COMMIT TRAN(使用ROLLBACK在那里)。这样我的CU就是原子的,全部或全部。

MERGE功能也会这样做。但MERGE的利弊是一个不同的主题。