在SQL Server 2008中处理插入/更新语句的最佳方法?

时间:2018-04-24 19:53:13

标签: sql-server sql-server-2008 sql-update deadlock sql-insert

我一直致力于新系统的设计,并且有许多情况,其中函数将处理插入/更新语句。通常使用服务器端语言以旧方式处理这种过程以确定将执行哪个查询。我想消除和改进的东西很少。这种方式有很多冗余代码,我们为Insert和Update重复两次相同的代码。在我们的旧系统中还存在一个问题,即我们从服务器遇到大量的死锁错误。我们的数据库设计非常差,这也可能是我们收集大量这些错误消息的众多因素之一。但是,在处理旧的遗留代码时,我已经学会了应该避免的内容,而不是重复相同的错误。所以这是在我当前的应用程序中处理插入/更新的代码示例:

<cfif len(FORM.frm_id)>
    <cfquery name="updateTbl" datasource="#dns#">
        UPDATE Table1
        SET
            testdt = <cfqueryparam value="#FORM.frm_testdt#" cfsqltype="cf_sql_date" maxlength="10" null="#!len(FORM.frm_testdt)#" />,
            location = <cfqueryparam value="#trim(FORM.frm_location)#" cfsqltype="cf_sql_varchar" maxlength="500" null="#!len(trim(FORM.frmhs_location))#" />,
            testwhy = <cfqueryparam value="#trim(FORM.frm_testwhy)#" cfsqltype="cf_sql_varchar" maxlength="50" null="#!len(trim(FORM.frm_testwhy))#" />
       WHERE id = <cfqueryparam value="#FORM.frm_id#" cfsqltype="cf_sql_integer" />
    </cfquery>
<cfelse>
    <cfquery name="insertTbl" datasource="#dns#">
       INSERT INTO Table1(
          testdt, location, testwhy
       )VALUES(
          <cfqueryparam value="#FORM.frm_testdt#" cfsqltype="cf_sql_date" maxlength="10" null="#!len(FORM.frm_testdt)#" />,
          <cfqueryparam value="#trim(FORM.frm_location)#" cfsqltype="cf_sql_varchar" maxlength="500" null="#!len(trim(FORM.frmhs_location))#" />,
          <cfqueryparam value="#trim(FORM.frm_testwhy)#" cfsqltype="cf_sql_varchar" maxlength="50" null="#!len(trim(FORM.frm_testwhy))#" />
       ) 
       SELECT SCOPE_IDENTITY() AS RecID 
    </cfquery>
</cfif>

正如你在上面的例子中看到的那样,有很多冗余但同时我不确定它是否有效。也有可能出现死锁的原因。所以我做了一些研究,以下是一些人建议的例子:

To avoid deadlocks and PK violations you can use something like this:

begin tran
if exists (select * from table with (updlock,serializable) where key = @key)
begin
   update table set ...
   where key = @key
end
else
begin
   insert into table (key, ...)
   values (@key, ...)
end
commit tran

OR

begin tran
   update table with (serializable) set ...
   where key = @key

   if @@rowcount = 0
   begin
      insert into table (key, ...) values (@key,..)
   end
commit tran

我不确定这两个例子是否是良好的做法,以及这两个解决方案是否存在任何先锋或缺点。然后我和其中一个级别的程序员进行了交谈,他们接着建议了。

-First use server side language (ColdFusion in our case) to determine if process is Insert or Update. 
-Then if it's insert do insert in the table with the blank data row.
-Run update and populate data. 

在他看来,我在上面用SQL beg if exists展示的两个例子在SQL中做了太多工作,我们应该通过服务器端语言处理插入更新的决定。他说他提供的解决方案将防止冗余(这是真的),并且更新比使用SQL插入数据更有效。因此,插入空/空行将节省一些时间。我想知道哪条路可走,而且很难决定。如果有人可以提供帮助并提供一些评论或示例,请告诉我。谢谢!

0 个答案:

没有答案