c# - "Pop"记录 -- 在同一语句中选择和删除 (SQL Server 2005)

标签 c# sql sql-server-2005

我有一个 C# 应用程序,大约有十几名员工同时使用。它只是从 SQL Server 2005 表中选择顶部记录,删除它,然后在表单上显示数据。
一旦选择了记录,就需要将其删除,这样 2 个人就不会抓取并处理同一条记录。
相当直接......

我不久前发现了一个建议(抱歉,找不到我从中获取的网站)在同一语句中执行 SELECT 和 DELETE 并使用此执行 SqlCommand.ExecuteReader()复合”语句:

SELECT TOP 1 * 
FROM Call_Table 
WHERE Call_Table.hold_call_till <= GetDate() 
ORDER BY Call_Table.attempts ASC, Call_Table.custno ASC;
DELETE 
FROM Call_Table
WHERE Call_Table.custno = (SELECT TOP 1 Call_Table.custno 
                           FROM Call_Table 
                           WHERE Call_Table.hold_call_till <= GetDate() 
                           ORDER BY Call_Table.attempts ASC, Call_Table.custno ASC);

到目前为止它一直运行良好,但我觉得我只是很幸运。我们正在招聘大约 5 名新员工,我想完全确定这将继续有效。

我有兴趣听听该领域更多经验丰富的 vert 的意见。

我应该坚持“如果它没有坏,就不要修复它”的方法吗?或者我应该加强我的游戏并使用某种 record_locks 或存储过程??

任何建议都将被公开接受。如有必要,我可以提供有关表或 C# 应用程序的更多信息。

最佳答案

我建议使用某种 optimistic concurrency control反而。不要删除记录,而是存储将在选择时获取的时间戳(或其他版本控制技术)。然后,如果用户编辑了某些内容,您可以检查以确保时间戳没有更改。如果有,则提示用户并重新加载新数据。如果没有,则保存数据并更新时间戳,这样拥有数据的任何其他人都不会覆盖您的更改。

Microsoft's article on optimistic concurrency

这是我的图形示例版本(使用编号系统而不是版本控制的时间戳)

Name|PhoneNum|Version
Joe |123-1234|1
  • UserA 和 UserB 在您的 UI 中提取 Joe 的数据

  • UserA修改并保存Joe

现在表格看起来像这样:

Name|PhoneNum|Version
Joe |555-5555|2
  • UserB 修改了 Joe 的数据版本 1 并保存。保存看到版本现在为 2,并提示用户 B 数据已更改。

更新

如果在用户阅读时无法访问该行,您有两种选择。

  • 您可以做您已经在做的事情,但由于OUTPUT,您不需要选择...删除(如上所述)。有了这个,您可以删除并获取值。

代码:

DECLARE @CallInfo TABLE (/*Call_Table Schema*/)

DELETE Call_Table
OUTPUT DELETED.* INTO @CallInfo 
WHERE Call_Table.custno = (SELECT TOP 1 Call_Table.custno 
                       FROM Call_Table 
                       WHERE Call_Table.hold_call_till <= GetDate() 
                       ORDER BY Call_Table.attempts ASC, Call_Table.custno ASC)

--The @CallInfo will have the info that you just deleted, so pass that back to the UI
SELECT * FROM @CallInfo
  • 您可以添加一个锁定列(使用锁定人员的用户 ID),在您选择数据之前立即更新该锁定列。如果用户崩溃或做了一些他们没有重置锁的事情,那么您唯一需要担心的就是它。我过去使用过这个系统,但如果大部分时间数据都被删除,那么复杂性可能不值得。如果您需要简单地更新数据,我发现这更有用。您可以添加这样的逻辑:如果同一个用户试图再次获取数据,那么就让他们获取吧,因为这可能是崩溃了。否则,您需要创建一个解锁系统。

关于c# - "Pop"记录 -- 在同一语句中选择和删除 (SQL Server 2005),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9827384/

相关文章:

c# - 为什么 LINQ 的连接方式与 SQL 不同?

sql - 为什么我不能在 SQL 中创建这个表?

sql-server - 在不对数据库名称进行硬编码的情况下从 T-SQL 存储过程引用另一个数据库

c# - NEST-低级搜索不返回日期

c# - 解析通过简单注入(inject)器注册的 ASP.NET Web 窗体图像控件派生类

sql - 加入第三个表以提取数据

php - 获取特定行上其值等于 1 的所有列名称

sql-server - SQL Server : replace sequence of same characters inside Text Field (TSQL only)

tsql - SQL Server 查询,在 View 中运行总计,在 A 列更改时重置

c# - 使用它的指针从托管 C# 中释放非托管内存