sql-server - 在 SQL Server 2008 中处理插入/更新语句的最佳方法?
问题描述
我一直致力于新系统的设计,在很多情况下函数将处理插入/更新语句。通常这种过程是使用服务器端语言以旧方式处理的,以确定将执行哪个查询。我想消除和改进的东西很少。这种方式有很多冗余代码,我们为插入和更新重复两次相同的代码。在我们的旧系统中也存在一个问题,我们有大量来自服务器的死锁错误。我们的数据库设计非常糟糕,这可能也是我们有大量错误消息的众多因素之一。然而,在处理旧的遗留代码时,我已经学会了应该避免什么,而不是重复同样的错误。所以这里是在我当前的应用程序中处理插入/更新的代码示例:
<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
或者
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 展示的两个示例在 SQLbeg if exists
中投入了太多工作,我们应该通过服务器端语言处理插入更新的决定。他说他提供的解决方案将防止冗余(这是真的),而且更新比使用 SQL 插入数据更有效。出于这个原因,插入空/空白行将节省一些时间。我想知道该走哪条路,很难决定。如果有人可以提供帮助并提供一些评论或示例,请告诉我。谢谢!
解决方案
推荐阅读
- i2c - 8051 MCU I2C 信号无响应
- java - Hibernate/JPA 将本机查询的结果映射到非实体持有实体
- html - HTML Audio 是否进行了一些更新?
- javascript - 无法获取 Request.azureMobile
- dart - 当我选择一个文本字段时,键盘会在它上面移动
- angular - “any[]”类型的参数不能分配给“PollModel”类型的参数。“any[]”类型中缺少属性“pollId”
- user-interface - 如何从滑块控件中读取值?
- android - 将 Android Studio 更新到 3.1.2 后,我收到“无法加载 AppCompat ActionBar 并出现未知错误。”
- perl - 如何修改现有程序中的“for”循环
- cors - 谷歌云存储不会将 CORS 标头添加到 OPTIONS 调用