Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi [SQL] updateable View (https://www.delphipraxis.net/12041-%5Bsql%5D-updateable-view.html)

Hansa 19. Nov 2003 12:04


[SQL] updateable View
 
Hi,

kann mich jemand hier aufklären, was hier genau geschieht ? Das ist aus dem Interbase 6 Data Definition Guide (S.190) :

SQL-Code:
CREATE TABLE Table1 (
  ColA INTEGER NOT NULL,
  ColB VARCHAR(20),
  CONSTRAINT pk_table PRIMARY KEY(ColA)
););

CREATE TABLE Table2 (
  ColA INTEGER NOT NULL,
  ColC VARCHAR(20)
  CONSTRAINT fk_table2 FOREIGN KEY REFERENCES Table1(ColA));

CREATE VIEW TableView AS SELECT Table1.ColA, Table1.ColB, Table2.ColC FROM Table1, Table2
  WHERE Table1.ColA = Table2.ColA;

CREATE TRIGGER TableView_Delete FOR TableView BEFORE DELETE AS BEGIN
  DELETE FROM Table1 WHERE ColA = OLD.ColA;
  DELETE FROM Table2 WHERE ColA = OLD.ColA;
END;


CREATE TRIGGER TableView_Update FOR TableView BEFORE UPDATE AS BEGIN
  UPDATE Table1 SET ColB = NEW.ColB WHERE ColA = OLD.ColA;
  UPDATE Table2 SET ColC = NEW.ColC WHERE ColA = OLD.ColA;
END;

CREATE TRIGGER TableView_Insert FOR TableView BEFORE INSERT AS BEGIN
  INSERT INTO Table1 values (NEW.ColA,NEW.ColB);
  INSERT INTO Table2 values (NEW.ColA,NEW.ColC);
END;
Schreibe den Text lieber auch noch dabei:
Zitat:

Updating views with triggers

Views that are based on joins—including reflexive joins—and on aggregates cannot be updated directly. You can, however, write triggers that will perform the correct writes to the base tables when a DELETE, UPDATE, or INSERT is performed on the view. This InterBase feature turns non-updatable views into updatable views. Tip You can specify nondefault behavior for updatable views, as well. InterBase does not
perform writethroughs on any view that has one or more triggers defined on it. This means that you can have complete control of what happens to any base table when users modify a view based on it.

For more information about updating and read-only views, see “Types of views: read-only and updatable” on page 131.

The following example creates two tables, creates a view that is a join of the two tables, and then creates three triggers—one each for DELETE, UPDATE, and INSERT—that will pass all updates on the view through to the underlying base tables.
Mehr steht da nicht. Schön und gut, aber folgendes verstehe ich nicht : die beiden Constraints verursachen einen Fehler. Sind sie auskommentiert läuft alles sauber ab. ColA läßt sich nicht verändern.

Smokey 19. Nov 2003 12:20

Re: [SQL] updateable View
 
Nuja steht ja im Text was da passiert :

Im Normalfall wird eine Änderung an Datensätzen über die View nicht gemacht, wenn diese über mehrere Tabellen geht.

Um das trotzdem machen zu können, werden Trigger gesetzt.
Triger überwachen quasi alle Aktionen die auf einer Datenbank ausgeführt werden.

Durch das :
SQL-Code:
 FOR TableView BEFORE UPDATE AS BEGIN
wird beispielsweise festgelegt, dass der Trigger alle Updateanweisungen der View "TableView" abfängt und mit dem darunter festgelegten Code reagiert (also den Update vom Trigger aus ausführt).

Hoffe das ist verständlich :wink:

Was die Constrains angeht, liegt es vermutlich an Syntaxfehlern.
Im ersten CREATE TABLE is meiner Meinung nach ne Klammer zuviel am Ende (was aber nicht stören sollte) und im CREATE TABLE der zweiten Tabelle fehlt zb nen Komma.

Am besten den Code nomma prüfen.

mfg SmK

Hansa 19. Nov 2003 13:17

Re: [SQL] updateable View
 
Liste der Anhänge anzeigen (Anzahl: 1)
Thx,

die Syntaxfehler waren nur temporär für den Beitrag. :mrgreen: Das richtige Script hängt hier dran. Und zwar kommt der Fehler bei REFERENCES. Das paßt ihm nicht. Danach kommen noch Folgefehler weil Table2 nicht erzeugt wurde. Was kann das sein ?

Und noch eine Verständnisfrage: was passiert, wenn Table 1 ein Insert braucht und Table 2 geupdatet werden muß ?? Auf jeden Fall ist es mir gelungen, mit dem View 2 unabhängige Tables zu bearbeiten, was angeblich nicht geht. Der Tip kommt übrigens direkt von Borland: "It's a handy feature !" :thuimb: DBgrids und ähnliche Geschichten könnten dadurch eventuell eine ganz andere Dimension erhalten, oder nicht ?

Smokey 19. Nov 2003 13:37

Re: [SQL] updateable View
 
Ich kenn mich mal absolut nicht mit Interbase aus und weiss nicht, wie die DB-Engine so Sachen handhabt.
Anscheinend hast du das ja alles in einem Script und da er bei REFERENCES abspringt würd ich von folgendem ausgehen :

Er erzeugt Table1 erstmal nur im Buffer und macht sie erst nach ausführen des kompletten Scripts sichtbar.

Versuch einfach mal 2 scripte zu machen, also eins für Table1 und eins für den Rest und schau dann mal, ob er immernoch abspringt, wenn Table1 schon durch das erste Script erstellt wurde.

Zu deiner Verständnisfrage : versteh ich nicht :stupid:

mfg
smk

Hansa 23. Nov 2003 00:03

Re: [SQL] updateable View
 
So, die Fehler sind weg. In meinem DBgrid kann ich nun 2 Tabellen bearbeiten, obwohl das angeblich nicht geht. Aber was nun ? Ich habe mir dazu die Lagerverwaltung als Bsp. ausgesucht. 8) Also gebe ich eine Art.Nr. ein und dann die Menge, wodurch dann die Lagertabelle aktualisiert wird. Dabei ist es mir aber noch nicht gelungen, die Lager.ID_art als ID von der Art.Tabelle einzufügen. Woran liegt das ? Lager.ID_ART ist so als FOREIGN KEY definiert:
SQL-Code:
ALTER TABLE LAGER ADD CONSTRAINT FK_LAGER FOREIGN KEY (ID_ART) REFERENCES ART (ID);

Hansa 5. Dez 2003 13:19

Re: [SQL] updateable View
 
Der View geht folgndermaßen:

SQL-Code:
CREATE VIEW LAGERVIEW( 
    IDART,
    IDLAGER,
    ARTNR,
    ARTBEZ,
    ARTBEZ2,
    ARTINH,
    LAGERMENGE)
AS
select ART.ID,LAGER.ID,ART.NR,ART.BEZ,ART.BEZ2,
       LAGER.MENGE from
  ART,LAGER
where ART.ID=LAGER.ID_ART;

ALTER TRIGGER LAGERVIEW_BD0 
AS
begin
  DELETE FROM LAGER WHERE ID_ART = OLD.IDART;
end
^

 ALTER TRIGGER LAGERVIEW_BI0 
AS
begin
  INSERT INTO LAGER (ID_ART,MENGE)
         VALUES (NEW.idart,NEW.LAGERMENGE);
end


ALTER TRIGGER LAGERVIEW_BU0 
AS
begin
  UPDATE LAGER SET
    MENGE=NEW.LAGERMENGE WHERE ID_ART=OLD.IDART;
end
^
Allerdings ist da noch ein Schönheitsfehler drin. Sofern ich die ID eines Artikels eingebe, so funktioniert alles. Nur weiß wohl keiner die ID eines Artikels. Hierzu bräuchte ich die Art.Nr. als Eingabefeld. Das müßte doch irgendwie auch gehen. Nur wie ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:27 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz