2014-10-28 45 views
0

我有一个表ID varchar(255)和done位。 我想获取发现的第一个ID,其中位未设置,同时获取也设置位。所以没有其他脚本实例使用相同的ID,并且没有竞争条件是可能的。更新和选择在MSSQL中的一个操作

import _mssql 
con = _mssql.connect(server='server', user='user', password='password', database='default') 

#these two in a single command 
con.execute_query('SELECT TOP 1 ID FROM tableA WHERE done=0') 
con.execute_query('UPDATE tableA SET done=1 WHERE ID=\''+id_from_above+'\'') 
for row in con: 
    #row['ID'] contains nothing as it last used with the UPDATE, not the SELECT 
    start_function(row['ID']) 

编辑(包括wewesthemenace的建议):

[...] 
con.execute_query('UPDATE tableA SET done = 1 WHERE ID = (SELECT TOP 1 ID FROM tableA WHERE done = 0)') 
for row in con: 
    #row['ID'] contains nothing as it last used with the UPDATE, not the SELECT 
    start_function(row['ID']) 

在Microsoft SQL Server企业版v9.00.3042.00工作,即SQL Server 2005的Service Pack 2的

编辑2:
已解答的问题引导我给出后续问题:While mssql query returns an affected ID use it in a while loop

+1

你想看看**交易**和**行锁定为此。在'execute_query()'中查找两个查询并不容易 - 你很好。“_ solution(afaik)。我发现的好介绍是** [this technet article](http://technet.microsoft.com/en-us/library/jj856598(v=sql.110).aspx)**,介绍它并解释** ACID **等 – funkwurm 2014-10-28 08:17:52

+0

我有一个单一的execute_quer()的解决方案..我现在编辑问题并添加我的解决方案。但非常感谢你的链接。 – 2014-10-28 09:24:54

回答

0

可能的解决方法,这在我的情况下工作。

con.execute_query('UPDATE tableA SET done=1 OUTPUT INSERTED.ID WHERE ID=(SELECT TOP(1) ID FROM tableA WHERE done=0)') 
for row in con: 
    #row['ID'] is exactly one ID where the done bit wasn't set, but now is. 
    start_function(row['ID']) 
1

这个怎么样?

UPDATE tableA SET done = 1 WHERE ID = (SELECT TOP 1 ID FROM tableA WHERE done = 0) 
+0

看起来不错,但我认为我不能'con for:start_function(row ['ID'])''中的行。为了澄清我自己,它做了它应该做的事情,但是我没有得到ID,我只是设置了完成位。 – 2014-10-28 07:46:20