Benutzer mit den meisten Antworten
View not updatable - Warum ?

Frage
-
Hallo,
ich habe mir eine View auf dem SQL-Server 2005 gebastelt. Diese besteht aus 2 Tabellen welche per Inner Join gejoint sind.
Leider kann ich immer nur eine Tabelle innerhalb der View updaten, da ansonsten die bekannt Meldung 'View or function 'View1' is not updatable because the modification affects multiple base tables' auftaucht.
Bei bisherigen Views hatte ich nie das Problem, daher ist mir nicht klar, woher das kommt bzw. warum das zu Stande kommt ? Und was sind für den Server 'Base Tables' ?
Lösung ist laut Recherche ein INSTEAD OF-Trigger, wobei ich mich damit irgendwie nicht so anfreunden kann.
Antworten
-
Du vermischt hier zwei Dinge.
Aber das ist nicht der Fall.
Mein Beispiel ist zur Demonstration des Begriffs Basistabelle.
Tabelle A 1-1 Tabelle B. Das ist alles.
Also:
USE tempdb ; GO CREATE TABLE A ( ID INT IDENTITY PRIMARY KEY , Payload NVARCHAR(255) NOT NULL ) ; CREATE TABLE B ( ID INT IDENTITY PRIMARY KEY , idA INT NOT NULL , Payload NVARCHAR(255) NOT NULL , CONSTRAINT FK_B_idA FOREIGN KEY ( idA ) REFERENCES A ( id ) ) ; GO CREATE VIEW AB AS SELECT A.ID AS AID , A.Payload AS APayload , B.ID AS BID , B.Payload AS BPayload FROM A INNER JOIN B ON A.ID = B.idA ; GO INSERT INTO A VALUES ( 'A1' ) ; INSERT INTO B VALUES ( 1, 'B1' ) ; GO -- Geht. UPDATE AB SET APayload = APayload + '1' ; GO -- Geht. UPDATE AB SET BPayload = BPayload + '2' ; GO -- Geht nicht. UPDATE AB SET APayload = APayload + '3' , BPayload = BPayload + '3' ; GO SELECT * FROM AB ; GO DROP VIEW AB ; DROP TABLE B ; DROP TABLE A ; GO
Bei anderen Views hatte ich das Problem bisher nie, darum frage ich mich, was hier den Unterschied ausmacht, welcher das Updaten verhindert.
Die Tatsache das eine UPDATE-Anweisung nur Werte in genau einer (Basis-)Tabelle ändern kann/darf.
Microsoft MVP Office Access
https://mvp.support.microsoft.com/profile/Stefan.Hoffmann- Als Antwort vorgeschlagen Falk Krahl Mittwoch, 6. Juli 2011 14:27
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 4. August 2011 11:50
-
Hallo,
OR-Mapper können auch nur SQL produzieren.
Und wenn zwei Tabellen (=> im ORM Klasse) über ein Fremdschlüsselbeziehung verknüpft sind,
so kann er dafür die benötigten zwei UPDATE-Anweisungen erzeugen und sie in einer Transaktion kapseln.Verwendest Du dort eine Sicht, so hast Du das gleiche Problem.
Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 4. August 2011 11:50
-
Autsch, noch 'ne Komplexitätsebene mehr? Nein, mit LINQ hat das erstmal nix zu tun. Eventuell ist dein verwendeter OR-Mapper in der Lage aus einem UPDATE zwei zu machen, aber dazu braucht es eben auch diese Information, welche Tabellen den betroffen sind.
Es stellt sich aber die Frage, warum du, wenn du eh einen OR-Mapper hast, nicht DML-Stored-Procedures arbeitest.
Somit lautet die Antwort: Keine Ahnung, einfach mal testen. Und vorher mal schauen, ob du die Basistabelleninformation auf Spaltenebene definieren kannst.
Microsoft MVP Office Access
https://mvp.support.microsoft.com/profile/Stefan.Hoffmann- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 4. August 2011 11:50
Alle Antworten
-
Siehe Aktualisierbare Sichten. Du kannst nur eine Basistabelle per DML aktualisieren. Ansonsten brauchst du zwingend einen INSTEAD OF-Trigger.
Microsoft MVP Office Access
https://mvp.support.microsoft.com/profile/Stefan.Hoffmann -
Na ja, in folgenden Beispiel wird mit einer UPDATE-Anweisung eine Änderung in zwei Basistabellen notwendig:
USE tempdb ; GO CREATE TABLE A ( ID INT IDENTITY PRIMARY KEY , Payload NVARCHAR(255) NOT NULL ) ; CREATE TABLE B ( ID INT IDENTITY PRIMARY KEY , idA INT NOT NULL , Payload NVARCHAR(255) NOT NULL , CONSTRAINT FK_B_idA FOREIGN KEY ( idA ) REFERENCES A ( id ) ) ; CREATE TABLE C ( ID INT IDENTITY PRIMARY KEY , idA INT NOT NULL , Payload NVARCHAR(255) NOT NULL , CONSTRAINT FK_C_idA FOREIGN KEY ( idA ) REFERENCES A ( id ) ) ; GO CREATE VIEW BC AS SELECT B.idA , B.ID AS BID , B.Payload AS BPayload , C.ID AS CID , C.Payload AS CPayload FROM B INNER JOIN C ON B.idA = C.idA ; GO CREATE VIEW AB AS SELECT A.ID AS AID , A.Payload AS APayload , BC.BID , BC.BPayload FROM A INNER JOIN BC ON A.ID = BC.idA ; GO INSERT INTO A VALUES ( 'A1' ) ; INSERT INTO B VALUES ( 1, 'B1' ) ; INSERT INTO C VALUES ( 1, 'C1' ) ; GO UPDATE AB SET APayload = APayload + '!' , BPayload = BPayload + '!' ; GO DROP VIEW AB ; DROP VIEW BC ; DROP TABLE C ; DROP TABLE B ; DROP TABLE A ; GO
Das einzige was noch in diesem Begriff steckt ist eigentlich einfach: Stell dir vor du änderst eine Sicht, welche selber aus Sichten besteht. Basistabelle meint die tatsächlich zugrunde liegenden Tabellen.
Microsoft MVP Office Access
https://mvp.support.microsoft.com/profile/Stefan.Hoffmann -
-
Du vermischt hier zwei Dinge.
Aber das ist nicht der Fall.
Mein Beispiel ist zur Demonstration des Begriffs Basistabelle.
Tabelle A 1-1 Tabelle B. Das ist alles.
Also:
USE tempdb ; GO CREATE TABLE A ( ID INT IDENTITY PRIMARY KEY , Payload NVARCHAR(255) NOT NULL ) ; CREATE TABLE B ( ID INT IDENTITY PRIMARY KEY , idA INT NOT NULL , Payload NVARCHAR(255) NOT NULL , CONSTRAINT FK_B_idA FOREIGN KEY ( idA ) REFERENCES A ( id ) ) ; GO CREATE VIEW AB AS SELECT A.ID AS AID , A.Payload AS APayload , B.ID AS BID , B.Payload AS BPayload FROM A INNER JOIN B ON A.ID = B.idA ; GO INSERT INTO A VALUES ( 'A1' ) ; INSERT INTO B VALUES ( 1, 'B1' ) ; GO -- Geht. UPDATE AB SET APayload = APayload + '1' ; GO -- Geht. UPDATE AB SET BPayload = BPayload + '2' ; GO -- Geht nicht. UPDATE AB SET APayload = APayload + '3' , BPayload = BPayload + '3' ; GO SELECT * FROM AB ; GO DROP VIEW AB ; DROP TABLE B ; DROP TABLE A ; GO
Bei anderen Views hatte ich das Problem bisher nie, darum frage ich mich, was hier den Unterschied ausmacht, welcher das Updaten verhindert.
Die Tatsache das eine UPDATE-Anweisung nur Werte in genau einer (Basis-)Tabelle ändern kann/darf.
Microsoft MVP Office Access
https://mvp.support.microsoft.com/profile/Stefan.Hoffmann- Als Antwort vorgeschlagen Falk Krahl Mittwoch, 6. Juli 2011 14:27
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 4. August 2011 11:50
-
Autsch, noch 'ne Komplexitätsebene mehr? Nein, mit LINQ hat das erstmal nix zu tun. Eventuell ist dein verwendeter OR-Mapper in der Lage aus einem UPDATE zwei zu machen, aber dazu braucht es eben auch diese Information, welche Tabellen den betroffen sind.
Es stellt sich aber die Frage, warum du, wenn du eh einen OR-Mapper hast, nicht DML-Stored-Procedures arbeitest.
Somit lautet die Antwort: Keine Ahnung, einfach mal testen. Und vorher mal schauen, ob du die Basistabelleninformation auf Spaltenebene definieren kannst.
Microsoft MVP Office Access
https://mvp.support.microsoft.com/profile/Stefan.Hoffmann- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 4. August 2011 11:50
-
Hallo,
OR-Mapper können auch nur SQL produzieren.
Und wenn zwei Tabellen (=> im ORM Klasse) über ein Fremdschlüsselbeziehung verknüpft sind,
so kann er dafür die benötigten zwei UPDATE-Anweisungen erzeugen und sie in einer Transaktion kapseln.Verwendest Du dort eine Sicht, so hast Du das gleiche Problem.
Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 4. August 2011 11:50