I am looking to update records in a table X, based on a table Y containing details of the updates. The difficulties are that
- One row of Y represents an update to a specified number of records in X.
- There may be multiple records in Y that specify different updates to records in X that are alike in the field by which they are matched; in this case, the updates should be applied to disjoint subsets of X.
Suppose X = materials(id, type_id, status, data)
; Y = material_updates(run_id, type_id, quantity, data)
(id
is just an internal primary key field)
Then what I'd like to do is (the equivalent of) to loop through a simple query like
SELECT *
FROM material_updates
WHERE run_id = :run;
and for each row
of the result set, apply something like
UPDATE TOP(row.quantity) materials
SET data = row.data, status = 1
WHERE status = 0 AND type_id = row.type_id;
(the change to status
happens to be constant in the problem I am trying to solve)
Sample data
materials_update table:
run_id type_id quantity data
1 1 3 42
1 2 2 69
1 2 1 105
materials table before the update:
type_id status data
1 1 17
1 1 17
1 0 0
1 0 0
1 0 0
1 0 0
2 0 0
2 0 0
2 0 0
2 0 0
materials table after the update:
type_id status data
1 1 17
1 1 17
1 1 42
1 1 42
1 1 42
1 0 0
2 1 69
2 1 69
2 1 105
2 0 0
I think it can be done using a cursor, but is this the best solution, or is there a more efficient way?