Skip to content Skip to sidebar Skip to footer

Why Can't I Use Select ... For Update With Aggregate Functions?

I have an application where I find a sum() of a database column for a set of records and later use that sum in a separate query, similar to the following (made up tables, but the i

Solution 1:

The syntax select . . . for update locks records in a table to prepare for an update. When you do an aggregation, the result set no longer refers to the original rows.

In other words, there are no records in the database to update. There is just a temporary result set.

Solution 2:

You might try something like:

<<LOCAL>>declare
  material_id materials.material_id%Type;
  cost        materials.cost%Type;
  total_cost  materials.cost%Type;
beginselect material_id,
         cost,
         sum(cost) over () total_cost
  into   local.material_id,
         local.cost,
         local.total_cost 
  from   materials
  where  material_id between1and3forupdateof cost;

  ...

endlocal;

The first row gives you the total cost, but it selects all the rows and in theory they could be locked.

I don't know if this is allowed, mind you -- be interesting to hear whether it is.

Solution 3:

For that, you can use the WITH command.

Exemple:

WITHresultAS (
  -- your select
) SELECT*FROMresultGROUPBY material_id;

Solution 4:

Is your problem "However, in theory someone could update the cost column on the materials table between the two queries, in which case the calculated percents will be off."?

In that case , probably you can simply use a inner query as:

SELECT material_id, cost/(SELECTSum(cost)
  FROM materials
  WHERE material_id >=0AND material_id <=10)
INTO v_material_id_collection, v_pct_collection
FROM materials
WHERE material_id >=0AND material_id <=10;

Why do you want to lock a table? Other applications might fail if they try to update that table during that time right?

Post a Comment for "Why Can't I Use Select ... For Update With Aggregate Functions?"