Reputation: 575
I have a table with a column ID
varchar(255) and a done
bit.
I want fetch the first ID
found, where the bit isn't set and whilst fetching also set the bit. So that no other instance of the script uses the same ID
and no race condition is possible.
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'])
edit (including the suggestion of 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'])
Working on Microsoft SQL Server Enterprise Edition v9.00.3042.00, i.e. SQL Server 2005 Service Pack 2
edit 2:
The answered question lead me to a follow-up question: While mssql query returns an affected ID use it in a while loop
Upvotes: 0
Views: 105
Reputation: 575
Possible solution, which works in my situation.
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'])
Upvotes: 0
Reputation: 31879
How about this one?
UPDATE tableA SET done = 1 WHERE ID = (SELECT TOP 1 ID FROM tableA WHERE done = 0)
Upvotes: 1