Обсуждение: Help with RULES - Please!

Поиск
Список
Период
Сортировка

Help with RULES - Please!

От
"Jeanna Geier"
Дата:
Hello List!

I'm still on the upwards learning curve with Postgres and this is my first
exposure to CREATE RULE....

I'm using Postgres 8.0.  First, let me describe how we're using it; we have
a view (measurement) that displays to the user the measurement of a selected
room on a drawing.  This is working OK.  However, on this view, there is a
drop-down box for the unit of measurement to display the details (i.e.:
feet, centimeters, meters, inches, etc).  Now, here's my problem, whenever
the user tries to select something else from the drop-down other than the
default (feet), the following message is being displayed: "Error updating
record in database: ERROR: cannot update a view."

Here is my elementdata.measurement View (as stored in Case Studio):

Create view "elementdata"."measurement" As

SELECT e.elementid, da.projectname, da.square_unit AS square_unit_sq,
a.area::integer * su.units_per_sqfoot::integer AS area_sq, e.slope::integer
AS slope_inches, sa.slopearea::integer * cu.units_per_cufoot::integer AS
slopearea_sq, da.linear_unit AS linear_unit_lin, (p.perimeter *
lu.units_per_foot::double precision)::integer AS perimeter_lin,
da.cubic_unit AS cubic_unit_cu, e.height::integer *
lu.units_per_foot::integer AS height_lin, e.height::double
precision::integer * a.area::integer * cu.units_per_cufoot::integer AS
volume_cu, da.drawingid

FROM
((((((((((SELECT perimeter.elementid, perimeter.perimeter FROM
elementdata.perimeter

UNION
    SELECT length.elementid, length.length AS perimeter FROM
elementdata.length)
UNION
    SELECT circumference.elementid, circumference.circumference AS perimeter
FROM elementdata.circumference) p
  LEFT JOIN elementdata.area a USING (elementid))
  LEFT JOIN element e USING (elementid))
  LEFT JOIN elementdata.slopearea sa USING (elementid))
  JOIN layer la USING (layerid))
  JOIN drawing da USING (drawingid))
  JOIN globaldata.linear_units lu USING (linear_unit))
  JOIN globaldata.square_units su USING (square_unit))
  JOIN globaldata.cubic_units cu USING (cubic_unit));

----------------------------------------------------------------------------
-----------------------------

And here is the update_measurement RULE (as stored in Case Studio):

CREATE RULE update_measurement AS ON UPDATE
    TO elementdata.measurement
    DO INSTEAD (UPDATE element SET height = (new.height_lin / (SELECT
linear_units.units_per_foot FROM globaldata.linear_units WHERE
((linear_units.linear_unit)::text =
                                 (old.linear_unit_lin)::text))), slope =
new.slope_inches WHERE (element.elementid = old.elementid); UPDATE drawing
SET linear_unit = new.linear_unit_lin, square_unit =
                                 new.square_unit_sq, cubic_unit =
new.cubic_unit_cu WHERE (drawing.drawingid = old.drawingid); );

----------------------------------------------------------------------------
-----------------------------

Where/why is the exception being thrown that the view cannot be updated?
How can I fix this??  Any help or guidance that anyone could provide will be
greatly appreciated!

If any more information is necessary from my end, please let me know.

Thanks,
-Jeanna


Re: Help with RULES - Please!

От
Tom Lane
Дата:
"Jeanna Geier" <jgeier@apt-cafm.com> writes:
> Here is my elementdata.measurement View (as stored in Case Studio):
> Create view "elementdata"."measurement" As
> ...
> And here is the update_measurement RULE (as stored in Case Studio):
> CREATE RULE update_measurement AS ON UPDATE
>     TO elementdata.measurement
>     DO INSTEAD (UPDATE element SET height = (new.height_lin / (SELECT
> ...

That rule should certainly trap any attempted update to
elementdata.measurement.  I suppose the error message is being thrown
about some other view ... it's unfortunate that it doesn't tell you
which one :-(.  Anyway the message definitely indicates an attempted
update against some view that has not got an unconditional ON UPDATE DO
INSTEAD rule, and this one does.

            regards, tom lane

Re: Help with RULES - Please!

От
Andrew Lazarus
Дата:
The JDBC driver makes its own determination of whether a recordset is
updateable, and it doesn't know about the RULEs on VIEWs. I found I
could fool it by creating an extra "oid" column in the view that I
knew was unique. The driver will use a column labeled oid as a primary
key for sending UPDATE commands to the back end.

In your code, you could probably just have SELECT element.elementid AS
oid, element.elemendid, etc. and change none of the rest of your code.

I don't know if this kludge is documented or guaranteed to work in
future versions.

Andrew Lazarus   drlaz@attglobal.net