Ažuriranje (update) view – a
Objavljeno: 10-03-2014 | Autor: Žana (Jovana) Baćović | Kategorija: T-SQL, View-ovi
Ознаке: Dinamicki pivot
0
View može da služi samo za čitanje podataka (read only view) ili da bude promjenljiv, odnosno da nad njim mogu da se pišu dml (Data Manipulation Language) naredbe update, insert i delete.
Read only view
Postoji više načina da view bude read only, navešću samo jedan pošto nisu tema ovog članka.
Read only svojstvo view-a može da se postigne i tako što se na kraju upita koji ga kreira doda union all sa uslovom koji neće biti zadovoljen.
Primjer: Nad Kefalo bazom izvršiti sledeći upit:
CREATE VIEW dbo.NadimciAutoraReadOnly (AutorID, Nadimak) AS SELECT AutorID, Nadimak FROM dbo.Autori UNION ALL SELECT 0,'' WHERE 1=0
Ukoliko pokušate da izvršite update:
UPDATE dbo.NadimciAutoraReadOnly SET Nadimak = 'Peyo nadimak' WHERE AutorID = 1001;
SQL Server će prijaviti grešku da view ima izvedeno ili konstantno polje i neće izmijeniti podatke.
View nad samo jednom tabelom
Kada view sadrži podatke iz samo jedne tabele i ne sadrži agregatne funkcije (a pri tome nije read only), može da se radi ažuriranje (update) view-a.
Primjer: Ako uzmemo view iz prethodnog primjera, bez union all dijela, naredbe update, insert i delete nad njim će se izvršiti bez problema.
CREATE VIEW dbo.NadimciAutora (AutorID, Nadimak) AS SELECT AutorID, Nadimak FROM dbo.Autori
Update iz prethodnog primjera, nad view-om koji nije read only će se izvršiti bez greške:
UPDATE dbo.NadimciAutora SET Nadimak = 'Peyo nadimak' WHERE AutorID = 1001;
Nakon update-a view-a, podaci su izmijenjeni u izvornoj tabeli, pa tako upit:
SELECT * FROM dbo.Autori WHERE AutorID = 1001;
daje sledeći rezultat:
Naredbe INSERT i DELETE će takođe biti izvršene i izazvaće izmjene u izvornoj tabeli, što možete da provjerite izvršavanjem sledeća četiri upita jedan za drugim:
INSERT INTO dbo.NadimciAutora (AutorID, Nadimak) VALUES (1020,'Test1'); SELECT * FROM dbo.Autori WHERE AutorID = 1020; DELETE FROM dbo.NadimciAutora WHERE AutorID = 1020; SELECT * FROM dbo.Autori WHERE AutorID = 1020;
View nad dvije ili više tabela
Ukoliko view ima kolone iz više od jedne tabele, moguće je ažuriranje view-a ukoliko se u jednoj naredbi mijenjaju kolone samo iz jedne tabele.
Izmjena kolona iz različitih tabela nije moguća u jednom update upitu.
Primjer: Nad Kefalo bazom kreirati sledeći view:
CREATE VIEW dbo.AutoriCrtaca (AutorID, Ime, Prezime, Crtac) AS SELECT A.AutorID, A.Ime, A.Prezime, F.Naziv AS Crtac FROM dbo.Autori A INNER JOIN dbo.CrtaniFilmovi_Rel_Autori R ON R.AutorID = A.AutorID INNER JOIN dbo.CrtaniFilmovi F ON F.CrtacID = R.CrtacID
Update koji mijenja podatke nad jednom od tabela će se izvršiti.
Primjer: Izmjena kolona Ime i Prezime iz tabele dbo.Autori, kao i izmjena kolone Crtac iz dbo.CrtaniFilmovi je moguća u dva odvojena update upita:
UPDATE dbo.AutoriCrtaca SET Ime = 'Novo ime Pjera', Prezime = 'Novo prezime Kulifora' WHERE AutorID = 1001; GO UPDATE dbo.AutoriCrtaca SET Crtac = 'Novo ime crtaca' WHERE AutorID = 1001;
SELECT upiti:
SELECT * FROM dbo.Autori WHERE AutorID = 1001; GO SELECT F.CrtacID, F.Naziv, R.AutorID FROM dbo.CrtaniFilmovi F INNER JOIN dbo.CrtaniFilmovi_Rel_Autori R ON R.CrtacID = F.CrtacID WHERE R.AutorID = 1001;
daju sledeće rezultate:
Ukoliko pokušamo da uradimo update kolona iz dvije različite tabele, SQL server će nam javiti grešku, jer nije dozvoljena izmjena nad više osnovnih tabela istovremeno.
Primjer: Sledeći upit:
UPDATE dbo.AutoriCrtaca SET Ime = 'Pjer', Crtac = N'Strumpfovi' WHERE AutorID = 1001;
vraća grešku:
View or function ‘dbo.AutoriCrtaca’ is not updatable because the modification affects multiple base tables.
Instead of trigger nad view–om
Postavljanjem instead of trigger–a nad view–om, moguće je izmijeniti kolone iz dvije različite tabele. U tom slučaju, parametre update komande preuzima trigger koji sadrži logiku koja omogućava izmjenu dvije ili više tabela.
Primjer: Kreirajte sledeći trigger:
USE SQL_KEFALO GO CREATE TRIGGER InsOfTrUpdAutoriCrtaca ON dbo.AutoriCrtaca INSTEAD OF UPDATE AS BEGIN IF (UPDATE(AutorID)) -- Ako se update-uje PK koji je FK drugoj tabeli BEGIN RAISERROR (N'Ne mozete da modifikujete PK u tabeli Autori, Transakcija je neuspjesna', 16, 1) RETURN END IF (UPDATE(Ime)) -- Ako se update-uje kolona Ime BEGIN UPDATE dbo.Autori SET Ime = I.Ime FROM inserted I INNER JOIN dbo.Autori A ON A.AutorID = I.AutorID WHERE A.AutorID = I.AutorID END IF (UPDATE(Prezime)) -- Ako se update-uje kolona Prezime BEGIN UPDATE dbo.Autori SET Prezime = I.Prezime FROM inserted I INNER JOIN dbo.Autori A ON A.AutorID = I.AutorID WHERE A.AutorID = I.AutorID END IF (UPDATE(Crtac)) -- Ako se update-uje kolona Crtac BEGIN UPDATE dbo.CrtaniFilmovi SET Naziv = I.Crtac FROM inserted I INNER JOIN dbo.CrtaniFilmovi_Rel_Autori R ON R.AutorID = I.AutorID INNER JOIN dbo.CrtaniFilmovi F ON F.CrtacID = R.CrtacID WHERE F.CrtacID = R.CrtacID END END
Nakon kreiranja instead of update trigera, možemo da provjerimo njegovu funkcionalnost izvršavanjem update-a koji mijenja podatke u dvije osnovne tabele.
Primjer: Sledeći upit modifikuje sve kolone view-a:
UPDATE dbo.AutoriCrtaca SET Ime = N'Pjer', Prezime =N'Kulifor', Crtac= N'Strumpfovi' WHERE AutorID = 1001;
Izvršavanjem select naredbe nad osnovnim tabelama, možete da potvrdite da su podaci izmijenjeni:
SELECT * FROM dbo.Autori WHERE AutorID = 1001; GO SELECT F.CrtacID, F.Naziv FROM dbo.CrtaniFilmovi F INNER JOIN dbo.CrtaniFilmovi_Rel_Autori R ON R.CrtacID = F.CrtacID WHERE R.AutorID = 1001;
Ovakav triger može da se koristi i za ažuriranje read only view-a.
Analogno naredbi update, odgovarajući instead of trigeri mogu da se kreiraju za naredbe insert i delete.