Views mit INSTEAD OF UPDATE-Trigger

by Wolfgang Kluge Mai 01, 2009 18:01

Ich stand vor der Problemstellung, eine Tabelle zu optimieren, da die Tabelle an vielen Stellen verwendet wird aber gleichzeitig dafür zu sorgen, dass die Umstellung "abwärtskompatibel" bleibt.

Die Tabelle ist schon etwas älter, mittlerweile gut gefüllt und es werden einige Daten ständig wiederholt - ich wollte also als erstes mal umstrukturieren. Mein erster Gedanke war, eine View zu verwenden, damit andere Abfragen noch genauso funktionieren wie zuvor. Am Anfang reicht es aus, die "wichtigsten" Abfragen zu optimieren und mit der Zeit könnte man dann langsam alle anderen Abfragen ändern sprich optimieren.

Gesagt, getan. Ich habe also die Tabellen angelegt und eine View nach dem Vorbild der Ursprungstabelle angelegt (und aus Performancegründen eine Indexed View verwendet). Damit auch INSERT-, UPDATE- und DELETE-Anweisungen weiterhin funktionieren, wurden entsprechende INSTEAD OF-Trigger geschrieben...

Doch dann durchkreuzte eine simple aber folgenreiche Fehlermeldung mein ganzes Vorhaben.

Msg 414, Level 16, State 1, Line <line>
UPDATE ist nicht zulässig, weil die Anweisung die "<view name>"-Sicht aktualisiert, die an einer Verknüpfung beteiligt ist und einen INSTEAD OF UPDATE-Trigger aufweist.

bzw.

Msg 414, Level 16, State 1, Line <line>
UPDATE is not allowed because the statement updates view <view name> which participates in a join and has an INSTEAD OF UPDATE trigger

Und nun? Es war schnell herausgefunden, dass mit "an Verknüpfung beteiligt" das UPDATE-Statement selbst gemeint ist. Nach einigen Tests und noch mehr Recherche fand ich dann heraus, dass es an dem UPDATE...FROM Statement liegt. Ein einfaches UPDATE-Statement(nach ANSI-Standard) funktioniert dagegen hervorragend.

Wozu diese Einschränkung gut sein soll weiß ich nicht. Bei Tabellen funktioniert das Spiel wie gewohnt. Nur Views unterliegen dieser Einschränkung.

Wer's selbst mal probieren will:

CREATE VIEW Test_InseteadOfUpdate
AS
    SELECT 1 AS test
GO

CREATE TRIGGER dbo.OnUpdate
            ON dbo.Test_InseteadOfUpdate
    INSTEAD OF UPDATE
AS BEGIN
    SET NOCOUNT ON
END
GO

--Funktioniert
UPDATE Test_InseteadOfUpdate
SET    test = 2
WHERE  test = 1

GO

--Fehler
UPDATE Test_InseteadOfUpdate
SET    test = upd.b
FROM   (
           SELECT 1 AS a,
                  2 AS b
       ) AS upd
WHERE test = upd.a


GO
DROP VIEW Test_InseteadOfUpdate

Der ANSI-Standard erlaubt auch Unterabfragen. Aber das bringt (zumindest mir) nicht viel, da die bisherigen Abfragen auch ohne jegliche Anpassung noch funktionieren sollen.

Das Gleiche gilt im Übrigen auch für DELETE-Anweisungen und INSTEAD OF DELETE-Trigger auf Views...

Kommentare

01.05.2009 18:04:31 #

trackback

Views mit INSTEAD OF UPDATE-Trigger

Sie wurden gekickt (eine gute Sache) - Trackback von  dotnet-kicks.de

dotnet-kicks.de |

Kommentare sind geschlossen

Powered by BlogEngine.NET 1.6.1.6
Theme by Mads Kristensen | Modified by Mooglegiant and me ;)