Informatyka sem. III studia inżynierskie Transport 2018/19 Lab 6 LAB 6 TRANSACTION, COMMIT, ROLLBACK, SET TRANSACTION ISOLATION LEVEL, UPDATE, INSERT INTO, ALTER TABLE, CREATE VIEW, CREATE TRIGGER, FUNCTION, STORED PROCEDURE, XML Utworzenie bazy danych Plik schemat6.sql zawiera polecenia SQL tworzące bazę o schemacie przedstawionym na Rys.1. platnosc * _faktury kwota data_wplaty klient imie nazwisko NIP miasto rabat faktura * numer _klienta data_wystawienia data_sprzedazy kwota _hurtowni hurtownia nazwa NIP miasto towar nazwa cena pozycja _faktury _towaru ilosc cena Rys. 1. Schemat bazy danych Sprzedaz Zasilenie bazy danych danymi Plik dane6.sql zawiera instrukcje INSERT INTO, które wstawiają przykładowe dane.
Modyfikacje danych 1. Dodanie nowej kolumny status do tabeli Faktura ALTER TABLE Faktura ADD stat INT CHECK(stat>=0 AND stat<=3) 2. Uaktualnienie wartości kolumny kwota w oparciu o pozycje faktury UPDATE faktura SET kwota = (SELECT SUM(cena*ilosc) FROM pozycja where pozycja._faktury = faktura.) 3. Uaktualnienie wartości kolumny status w oparciu o sumę płatności CREATE VIEW Wplaty SELECT p._faktury,f.kwota,sum(p.kwota) as wplaty From Platnosc p Inner Join Faktura As f on p._faktury = f. Group by p._faktury,f.kwota UPDATE Faktura set stat= (SELECT CE WHEN w.kwota<w.wplaty THEN 3 WHEN w.kwota=w.wplaty THEN 2 WHEN w.wplaty >0 THEN 1 ELSE 0 FROM Wplaty w WHERE w._faktury = Faktura.) 4. Ustalenie rabatów klientów w oparciu o historię zakupów Klientom regulującym płatności i kupującym dużo przydziel rabat 5, 10 lub 20%. CREATE VIEW Klienci SELECT f._klienta,sum(f.kwota) kwota,sum(w.wplaty) as wplaty FROM Faktura As f LEFT OUTER JOIN Wplaty w ON w._faktury=f. GROUP BY f._klienta UPDATE Klient SET rabat= (SELECT IIF(wplata>=kwota,CE WHEN kwota > 1000 THEN 20 WHEN kwota > 500 THEN 10 ELSE 5,0) FROM Klienci WHERE Klient.=Klienci._klienta )
Wyszukiwanie danych 1. Wyszukaj najlepiej sprzedający się towar (ilość) 2. Wyszukaj najlepiej sprzedający się towar (łączna kwota) 3. Ranking klientów pod względem wydanych kwot 4. Wyszukaj klientów zadłużonych 5. Wyszukaj klientów mających nadpłatę 6. Pokaż łączne kwoty wystawionych faktur z podziałem na hurtownie w poszczególnych miesiącach.
Triggery, Funkcje, Procedury Składowane 1. Dodanie nowych kolumn do tabeli Klient ALTER TABLE Klient ADD data_kreacji datetime, data_modyfikacji datetime, s_kreatora int, s_modyfikatora int 2. Dodanie Triggerów CREATE TRIGGER TR_Klient_Insert ON Klient AFTER INSERT -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. UPDATE Klient SET data_kreacji=getdate(),data_modyfikacji=getdate(),s _kreatora=suser_(), s_modyfikatora=suser_() -- Insert statements for trigger here CREATE TRIGGER TR_Klient_Update ON Klient AFTER UPDATE -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. UPDATE Klient SET data_modyfikacji=getdate(),s_modyfikatora=suser_( ) -- Insert statements for trigger here
3. Utworzenie funkcji skalarnej CREATE FUNCTION Get_KlientRabat ( @_faktury int ) RETURNS int DECLARE @rabat INT SELECT @rabat=rabat FROM Klient INNER JOIN Faktura on Faktura._klienta=Klient. WHERE Faktura.=@_faktury RETURN @rabat 4. Utworzenie procedury składowanej CREATE PROCEDURE sp_przeliczpozycje -- Add the parameters for the stored procedure here @_fakt INT UPDATE Faktura SET kwota = (SELECT SUM(cena) FROM pozycja WHERE pozycja._faktury=@_fakt) WHERE Faktura.=@_fakt 5. Utworzenie triggera ALTER TRIGGER [dbo].[tr_pozycja_insert] ON [dbo].[pozycja] AFTER INSERT -- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements. DECLARE @_fakt INT, @ile INT, @_tow INT, @cen DECIMAL(10,2), @rab INT; SELECT @_fakt=_faktury, @ile=ilosc, @_tow=_towaru FROM inserted; SELECT @cen=cena FROM towar WHERE towar.=@_tow; SET @rab=dbo.get_klientrabat(@_fakt); UPDATE pozycja SET cena = @cen*(100- @rab)*@ile/100 ; EXECUTE dbo.sp_przeliczpozycje @_fakt; -- Insert statements for trigger here 6. Historia zmian, Ostrzeżenia CREATE TABLE [dbo].[klient_historia]( [] [int] IDENTITY(1,1) NOT NULL, [_klienta] [int] NULL, [imie] [nchar](20) NULL, [nazwisko] [nchar](30) NULL, [NIP] [nchar](10) NULL, [data_modyfikacji] [datetime] NULL, [s_modyfikatora] [int] NULL, CONSTRAINT [PK_klient_historia] PRIMARY KEY CLUSTERED ( [] C )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[klient_historia] WITH CHECK ADD CONSTRAINT [FK_klient_historia_klient] FOREIGN KEY([_klienta]) REFERENCES [dbo].[klient] ([]) GO ALTER TABLE [dbo].[klient_historia] CHECK CONSTRAINT [FK_klient_historia_klient] ALTER TRIGGER [dbo].[tr_klient_update] ON [dbo].[klient] AFTER UPDATE -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements.
UPDATE Klient SET data_modyfikacji=getdate(),s_modyfikatora=suser_(); DECLARE @imie NCHAR(20), @nazwisko NCHAR(30), @_klienta INT; SELECT @imie=imie, @nazwisko=nazwisko, @_klienta = from inserted; INSERT INTO klient_historia(_klienta,imie,nazwisko,data_modyfikacji,s_modyfikatora) VALUES (@_klienta,@imie,@nazwisko,getdate(),suser_()); ALTER TRIGGER [dbo].[tr_klient_insert] ON [dbo].[klient] AFTER INSERT -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. UPDATE Klient SET data_kreacji=getdate(),data_modyfikacji=getdate(),s_kreatora=suser_(), s_modyfikatora=suser_() -- Insert statements for trigger here DECLARE @imie NCHAR(20), @nazwisko NCHAR(30), @_klienta INT; SELECT @imie=imie, @nazwisko=nazwisko, @_klienta = from inserted; INSERT INTO klient_historia(_klienta,imie,nazwisko,data_modyfikacji,s_modyfikatora) VALUES (@_klienta,@imie,@nazwisko,getdate(),suser_());
Transakcje 1. W zakładce New Query uruchamiamy select imie,nazwisko from klient otrzymując przykładowy wynik 2. W nowej zakładce New Query uruchamiamy TRANSACTION T1 insert into klient (,imie,nazwisko) VALUES (5,'Marian','Nowak') (1 row(s) affected) 3. W pierwszej zakładce NewQuery ponownie uruchamiamy select imie,nazwisko from klient otrzymujemy: Otwieramy Activity Monitor 4. W drugiej zakładce uruchamiamy COMMIT TRANSACTION T1
co automatycznie zakończy oczekiwanie na wyniki w zakładce pierwszej. Powtarzamy pkt 1-4 po obniżeniu ISOLATION LEVEL do READ UNCOMMITTED (domyślny ISOLATION LEVEL to READ COMMITTED czyli czytaj tylko rekordy zatwierdzone). 1. TRANSACTION T1 insert into klient (,imie,nazwisko) VALUES (6,'Marcin','Nowakowski') 2. SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED select imie,nazwisko from klient Wzimy rekord niezatwierdzony 3. Cofamy transakcję ROLLBACK TRANSACTION T1 4. select imie,nazwisko from klient
XML select imie,nazwisko,faktura.numer,faktura.data_wystawienia,kwota, ilosc,pozycja.cena,towar.nazwa from klient inner join faktura on faktura._klienta=klient. inner join pozycja on pozycja._faktury = faktura. inner join towar on pozycja._towaru = towar. FOR XML AUTO, ROOT('Klienci'), ELEMENTS <Klienci> <klient> <imie>jan </imie> <nazwisko>kowalczyk </nazwisko> <faktura> <numer>1/2016 </numer> <data_wystawienia>2016-12-04</data_wystawienia> <kwota>270.00</kwota> <pozycja> <ilosc>5.00</ilosc> <cena>90.00</cena> <towar> <nazwa>zeszyt </nazwa> </towar> </pozycja> <pozycja> <ilosc>1.00</ilosc> <cena>90.00</cena> <towar> <nazwa>blok </nazwa> </towar> </pozycja> <pozycja> <ilosc>10.00</ilosc> <cena>90.00</cena> <towar> </towar> </pozycja> </faktura> </klient> </Klienci> <nazwa>zeszyt </nazwa> select kolumna.value('(./klienci/klient)[1]', N'varchar(25)') select kolumna.value('(./klienci/klient/faktura)[1]', N'varchar(25)') select kolumna.value('(./klienci/klient/faktura/pozycja)[1]', N'varchar(25)')