Thread: About rules on views and M$ Access

About rules on views and M$ Access

From
Davide Romanini
Date:
Hi,

I've some problems releted to updating columns of a view, from M$ Access
through ODBC. Well let me explain.

I've a view that takes data from two different tables and have some
calculated columns.
I simply want to modify data of some of the non-calculated columns, so I
wrote a rule that on the UPDATE
event on the view performs another UPDATE on the table I want to modify.

This is the view:

CREATE VIEW ordini_emessi_view AS
   SELECT "Dettagli Ordini Emessi"."Ordine numero",
                  "Dettagli Ordini Emessi"."IDArticolo",
                  "Dettagli Ordini Emessi"."Quantità",
                  "Dettagli Ordini Emessi"."QuantitàEvasa",
                  "Anagrafica Articoli Tab"."CodiceAcquisto",
                  ("Costo" * (1 - ("Sconto" / 100))) AS "CostoEffettivo",
                  "Anagrafica Articoli Tab"."MinimoAcquisto",
                  "Anagrafica Articoli Tab"."Collegamento",
                  "Descrizione degli articoli"."Descrizione",
                  "Dettagli Ordini Emessi"."PrezzoUnit",
                  "Descrizione degli articoli"."Unità di Fatturazione"
AS "UDM"
  FROM    (("Anagrafica Articoli Tab" JOIN "Dettagli Ordini Emessi"
                               ON (("Anagrafica Articoli
Tab"."IDArticolo" = "Dettagli Ordini Emessi"."IDArticolo")))
                     JOIN "Descrizione degli articoli"
                               ON (("Anagrafica Articoli
Tab"."Collegamento" = "Descrizione degli articoli"."IDART")));

I'd want to modify only the columns of "Dettagli Ordini Emessi" so the
rule is:

CREATE OR REPLACE RULE ordini_emessi_update AS ON UPDATE TO
ordini_emessi_view
DO INSTEAD
   UPDATE "Dettagli Ordini Emessi" SET "Ordine numero"=NEW."Ordine numero",

"IDArticolo"=NEW."IDArticolo", "Quantità"=NEW."Quantità",

"QuantitàEvasa"=NEW."QuantitàEvasa", "PrezzoUnit"=NEW."PrezzoUnit"
    WHERE "Ordine numero"=OLD."Ordine numero" AND
"IDArticolo"=OLD."IDArticolo";

It all works fine if I do updates in this form:

UPDATE ordini_emessi_view SET  field=something, ...
   WHERE "Ordine numero"=something AND "IDArticolo"=something;

I've problems using M$ Access because it sends UPDATES with a lot of
fields in the WHERE clause. It always includes the
calculated column "CostoEffettivo" that makes PostgreSQL updating nothing:

UPDATE "ordini_emessi_view" SET "Quantità"='360'::float4
WHERE "Ordine numero" = 620 AND "IDArticolo" = 3170
AND "Quantità" = '350'::float4 AND "QuantitàEvasa" = '360'::float4
AND "CostoEffettivo" = '1.44232004547119'::double precision   --This
line makes problems!
AND "MinimoAcquisto" = '18'::float4 AND "Collegamento" = 2793
AND "PrezzoUnit" = '1.4423'::float8 AND "UDM" = 'mq';

Please note that if I comment that line and send the query manually to
PG it works perfectly.
I think that when PG reads this SQL it looks in the view for a row
satisfacting the WHERE conditions, then
if it founds it performs the update, elsewhere it does nothing.
But it simply doesn't find any row with
"CostoEffettivo"='1.44232004547119' and this is probably due to internal
handling of double precision numbers, I don't know exactly why. The
query successes if I cast the column "CostoEffettivo" as text.
Remember anyway that I can't change the queries the Access sends to ODBC!

Please, if you have suggestions about solving this problem, tell me!

Regards, Romaz




Re: About rules on views and M$ Access

From
"Tambet Matiisen"
Date:
>
> Please note that if I comment that line and send the query
> manually to
> PG it works perfectly.
> I think that when PG reads this SQL it looks in the view for a row
> satisfacting the WHERE conditions, then
> if it founds it performs the update, elsewhere it does nothing.
> But it simply doesn't find any row with
> "CostoEffettivo"='1.44232004547119' and this is probably due
> to internal
> handling of double precision numbers, I don't know exactly why. The
> query successes if I cast the column "CostoEffettivo" as text.
> Remember anyway that I can't change the queries the Access
> sends to ODBC!
>
> Please, if you have suggestions about solving this problem, tell me!
>

This is because Access uses so called "optimistic locking". It remembers the last values of record and updates the
recordONLY when noone hasn't changed it. I use similar approach in my application and I also have this problem. 

Actually, this wouldn't be problem, if the view had primary key. Because generally only those fields get added to WHERE
clause,that have been changed (you never change "CostoEffettivo"?). But in case of view, all fields are added, because
thisis the only possible way to identify the changed record. If you try the same thing on ordinary table, you see that
onlyprimary key and old value of changed field are in where clause: primary key to identify the record and old value to
implementoptimistic locking. 

I'm aware of only one solution to this problem - create table with the same fields as view and make sure it has a
primarykey. Then create SELECT and UPDATE rules on that table with appropriate SELECT and UPDATE queries. This tricks
Accessto think that the view has primary key. You cannot just add primary key to existing view. 

As you see, this is quite ugly and incompatible solution. But only alternative I know is to change database design.

  Tambet

Re: About rules on views and M$ Access

From
Jeff Eckermann
Date:
--- Davide Romanini <romaz@libero.it> wrote:
(snipped)
> But it simply doesn't find any row with
> "CostoEffettivo"='1.44232004547119' and this is
> probably due to internal
> handling of double precision numbers, I don't know
> exactly why. The
> query successes if I cast the column
> "CostoEffettivo" as text.
> Remember anyway that I can't change the queries the
> Access sends to ODBC!
>
Not quite true: you could always use unbound forms
etc, though that lets you in for a lot of extra work
;-)
Your queries suggest that "CostoEffettivo" is a
display field, i.e. it is not used in computations and
will not be updated directly.  If so, try casting it
to text in your view definition, and have it displayed
as text in your form.  At least the value should agree
that way, so your updates would succeed.
As for controlling the way Access composes its SQL: I
don't know whether that is possible, perhaps you could
post the question to an Access NG/List.

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

Re: About rules on views and M$ Access

From
Davide Romanini
Date:
Jeff Eckermann ha scritto:

> Not quite true: you could always use unbound forms
> etc, though that lets you in for a lot of extra work
> ;-)
> Your queries suggest that "CostoEffettivo" is a
> display field, i.e. it is not used in computations and
> will not be updated directly.  If so, try casting it
> to text in your view definition, and have it displayed
> as text in your form.  At least the value should agree
> that way, so your updates would succeed.
> As for controlling the way Access composes its SQL: I
> don't know whether that is possible, perhaps you could
> post the question to an Access NG/List.
>

Thanks I've solved in this way. The field "CostoEffettivo" is used in
the form only to do a calcul in VBA, I only had to place a Val() in that
piece of code.

Some note about the very stupid behaviour of Access. When I link an ODBC
table, if it has not a unique identifier such a primary key, Access asks
me for that. If I don't choose any field Access will refuse to make any
update or insert in the table. So, I think, if I choose the primary key
fields for the table, Access will use only that fields to do updates.
But, NO, Access will use practically all the fields of the table (really
not all the fields, don't know what criteria it uses to choose them), so
I ask: why it needs to know a unique identifier when it link tables? It
could simply use *always* all the fields of the table as unique identifier!

Anyway, thanks a lot for your answers.

Bye, Romaz