SQL - notatki z wykładu część druga wykład PDF

Title SQL - notatki z wykładu część druga wykład
Course Wstęp do programowania
Institution Wyższa Szkoła Biznesu – National-Louis University
Pages 13
File Size 159.1 KB
File Type PDF
Total Downloads 56
Total Views 617

Summary

Język SQL cz.Tworzenie i modyfikowanie tabel, wstawianie,kasowanie i aktualizacja rekordów.Zdania CREATE TABLE, INSERT INTO, ALTERTABLE, DELETE.PRIMARY KEY – klucz główny. Jest to kolumna w tabeli, która musi być w każdym wierszuuzupełniona (NOT NULL) oraz wartość w każdym wierszu musi unikalna (w o...


Description

Język SQL cz.2. Tworzenie i modyfikowanie tabel, wstawianie, kasowanie i aktualizacja rekordów. Zdania CREATE TABLE, INSERT INTO, ALTER TABLE, DELETE. PRIMARY KEY – klucz główny. Jest to kolumna w tabeli, która musi być w każdym wierszu uzupełniona (NOT NULL) oraz wartość w każdym wierszu musi unikalna (w obrębie tabeli). Klucz główny może być tylko jeden w tabeli. Może się jednak zdarzyć, że klucz główny (jeden) składa się z kilku kolumn, np. dwóch. W przypadku klucza złożonego z dwóch kolumn wartość pary (kolumna1, kolumna2) musi być unikalna dla każdego wiersza. UNIQUE – ograniczenie podobne do klucza głównego, jednak w kolumnie może być NULL, ponadto w tabeli można zdefiniować więcej niż jedno ograniczenie UNIQUE. --Tworzenie tabel CREATE TABLE Pracownicy( NrPrac INT pRiMaRY KeY, PESEL CHAR(11) UNIQUE NOT NULL, Nazwisko NVARCHAR(50) NOT NULL, Imie NVARCHAR(50) NOT NULL, Stawka MONEY NULL, [Data urodzenia] DATE, LiczbaDzieci TINYINT, Premia DECIMAL(5,3) ) select * from pracownicy

Dodawanie (wpisywanie) wierszy do tabeli – zdanie INSERT INTO … VALUES … . INSERT INTO Pracownicy VALUES(1,'12345678911','Kowal','Jan',3200.0,'1985-01-01',0.0,12.0) SELECT * FROM Pracownicy --To jest źle - powtórzenie klucza INSERT INTO Pracownicy VALUES(1,'12345678911','Wrona','Anna',3200.0,'1985-01-01',0,12.0) SELECT * FROM Pracownicy --To też jest źle - powtórzenie w polu UNIQUE (PESEL) INSERT INTO Pracownicy VALUES(2,'12345678911','Wrona','Anna',3200.0,'1985-01-01',0,12.0) SELECT * FROM Pracownicy INSERT INTO Pracownicy VALUES(2,'12345678910','Wrona','Anna',4200.0,'1985-01-01',0,11.0) SELECT * FROM Pracownicy INSERT INTO Pracownicy VALUES(3,'223456','Zielinski','Adam',2200.0,'1989-10-02',1,11.0) SELECT * FROM Pracownicy

SELECT * FROM PRacoWniCy WHERE PESEL = '223456' SELECT * FROM Pracownicy --Inny sposób tworzenia klucza głównego: CREATE TABLE Pracownicy( NrPrac INT, PESEL CHAR(11) UNIQUE NOT NULL, Nazwisko NVARCHAR(50) NOT NULL, Imie NVARCHAR(50) NOT NULL, Stawka MONEY NULL, [Data urodzenia] DATE, LiczbaDzieci TINYINT, Premia DECIMAL(5,3), PRIMARY KEY(NrPrac) ) --Jeszcze inny sposób tworzenia klucza głównego: CREATE TABLE Pracownicy( NrPrac INT, PESEL CHAR(11) UNIQUE NOT NULL, Nazwisko NVARCHAR(50) NOT NULL, Imie NVARCHAR(50) NOT NULL, Stawka MONEY NULL, [Data urodzenia] DATE, LiczbaDzieci TINYINT, Premia DECIMAL(5,3), CONSTRAINT PK1 PRIMARY KEY(NrPrac) )

--Jeszcze inny sposób tworzenia klucza głównego --Najpierw usuńmy klucz główny (bez usuwania kolumny): ALTER TABLE Pracownicy DROP CONSTRAINT [PK__PRacoWni__5D68336ED4F9B178] INSERT INTO Pracownicy VALUES(3,'223456211','Zielinska','Anna',2200.0,'1989-10-02',1,11.0) SELECT * FROM Pracownicy DELETE FROM Pracownicy WHERE Nazwisko = 'Zielinska' SELECT * FROM Pracownicy

Dodanie klucza głównego zdaniem ALTER TABLE ALTER TABLE Pracownicy ADD CONSTRAINT PK1 PRIMARY KEY(NrPrac) --Usunięcie kolumny ALTER TABLE Pracownicy DROP COLUMN Premia --Dodanie kolumny ALTER TABLE Pracownicy ADD Premia INT SELECT * FROM Pracownicy

--Można zmienić ograniczenie np. z NULL na NOT NULL (lub odwrotnie), o ile nie jest --to sprzeczne z istniejącymi w kolumnie danymi. Typ danych można też zmienić, o ile --może być zrealizowana konwersja. Na przykład można zmienić typ MONEY na INT, ale --wówczas wszystkie liczby wpisane do kolumny zostaną zaokrąglone do najbliższej --liczby całkowitej – zgodnie z typem INT. Typ danych musi być podany nawet, jeśli --zmieniane jest tylko ograniczenie z NULL na NOT NULL lub odwrotnie. ALTER TABLE Pracownicy ALTER COLUMN Premia INT NOT NULL

Ograniczenie CHECK (CHECK CONSTRAINT). CREATE TABLE Pracownicy( Nr INT PRIMARY KEY, Nazwisko NVARCHAR(50) NOT NULL, Imie NVARCHAR(50) NOT NULL, Stawka MONEY, DataZatrudnienia DATE, LiczbaDzieci TINYINT )

Ograniczenie CHECK będzie sprawdzane przy wprowadzaniu danych i przy ich modyfikacji. Operacja, która wprowadzałaby chociaż jeden rekord do tabeli, który nie spełnia warunku podanego po słowie CHECK, zostanie odrzucona przez system. ALTER TABLE Pracownicy ADD CONSTRAINT CK1_Pracownicy CHECK (Stawka BETWEEN 1000 AND 10000) INSERT INTO Pracownicy VALUES (1,'Kowal','Piotr', 500, '2010-01-01',2) --To się nie uda – za mało wartości, powinno być tyle ile kolumn: INSERT INTO Pracownicy VALUES (1,'Kowal','Piotr') --Rozwiązanie poprawne: INSERT INTO Pracownicy VALUES (1,'Kowal','Piotr',NULL,NULL,NULL) SELECT * FROM Pracownicy

Kasowanie wierszy – zdanie DELETE. DELETE FROM Pracownicy WHERE Nr=1

Uwaga. Nie zawsze da się łatwo usunąć wiersz w tabeli. Mogą być w bazie danych włączone mechanizmy, które zablokują kasowanie wiersza, do którego są odwołania w innej tabeli (lub w większej liczbie innych tabel). Jeśli w zdaniu DELETE nie umieścimy klauzuli WHERE, to zostaną usunięte wszystkie rekordy w tabeli. Może to być niebezpieczne! DELETE FROM Pracownicy

Jeśli chcemy usunąć wszystkie rekordy z tabeli a tabela jest bardzo duża, do operacja delete może stosunkowo długo trwać. Powodem jest konieczność bieżącego zapisywania wszystkich zmian danych w tzw. dzienniku transakcji. Dotyczy to również kasowania rekordów – dokładne informacje o wszystkich skasowanych rekordach są wpisywane do pliku dziennika transakcji (transaction log). Takie działanie umożliwia przywrócenie zawartości tabeli na przykład w przypadku, gdyby podczas usuwania nastąpiła awaria systemu. Istnieje bardzo szybki sposób kasowania wszystkich rekordów w tabeli – bez zapisywania informacji w dzienniku transakcji: TRUNCATE TABLE Pracownicy

Jednak ta metoda jest mniej bezpieczna od DELETE (w przypadku awarii znacznie trudniej jest odzyskać informacje o skasowanych rekordach). Wstawianie wiersza z uzupełnionymi niektórymi kolumnami. INSERT INTO Pracownicy (Nr, Nazwisko, Imie) – w nawiasach umieszczone są nazwy kolumn VALUES (1,'Kowal','Piotr')

Powyższa operacja uda się jednak tylko wtedy, jeśli wstawiamy dane do wszystkich wymaganych kolumn (wszystkich z ustawieniem NOT NULL, w tym do klucza głównego).

Automatyczne numerowanie rekordów w tabeli: Dwa mechanizmy – własność IDENTITY oraz obiekt SEQUENCE. Własność IDENTITY – tylko w systemie Microsoft SQL Server. DROP TABLE Pracownicy CREATE TABLE Pracownicy( Nr INT PRIMARY KEY IDENTITY(1,1), Nazwisko NVARCHAR(50) NOT NULL, Imie NVARCHAR(50) NOT NULL, Stawka MONEY, DataZatrudnienia DATE, LiczbaDzieci TINYINT ) --Nie wprowadzamy danych do kolumny Nr, dane te zostaną wprowadzone automatycznie INSERT INTO Pracownicy(Nazwisko, Imie, Stawka, DataZatrudnienia,LiczbaDzieci) VALUES ('Kowal','Piotr', 1500, '2010-01-01',2) SELECT * FROM Pracownicy --Jeśli jedyną kolumną, do której nie wpisujemy wartości jest kolumna z włączonym automatycznym numerowaniem, wówczas po nazwie tabeli nie trzeba wpisywać nazw kolumn. INSERT INTO Pracownicy VALUES ('Nowak','Anna', 1600, '2012-01-01',2) SELECT * FROM Pracownicy INSERT INTO Pracownicy VALUES ('Wrona','Adam', 1100, '2015-01-01',2)

SELECT * FROM Pracownicy DELETE FROM Pracownicy WHERE Nr=2 --Po skasowaniu danych pracownika nr 2 w kolumnie Nr liczba ta nie będzie już występować (oczywiście NIE następuje żadne przenumerowanie pracowników). SELECT * FROM Pracownicy

--Nowy pracownik dostanie kolejny nowy numer: INSERT INTO Pracownicy VALUES ('Nowak','Anna', 1600, '2012-01-01',2) SELECT * FROM Pracownicy DELETE FROM Pracownicy WHERE Nr=4 --Próba dopisania pracownika z jawnym podaniem jego numeru zakończy się błędem, ponieważ kolumna Nr ma włączoną własność Identity. W komunikacie o błędzie pojawi się informacja co należy zrobić, by można było samemu wprowadzić dane do takiej kolumny. INSERT INTO Pracownicy VALUES (2,'Nowak','Anna', 1600, '2012-01-01',2) --Jednym z warunków jest włączenie opcji IDENTITY_INSERT dla tabeli. SET IDENTITY_INSERT Pracownicy ON --To jeszcze nie wystarczy, próba wykonania poniższego zdania zakończy się niepowodzeniem: INSERT INTO Pracownicy VALUES (2,'Nowak','Anna', 1600, '2012-01-01',2) --W celu osiągnięcia pożądanego efektu należy w zdaniu INSERT po nazwie tabeli podać nazwy wszystkich kolumn, do których wprowadzane są dane ŁĄCZNIE z kolumną Identity INSERT INTO Pracownicy(Nr,Nazwisko,Imie,Stawka,DataZatrudnienia, LiczbaDzieci) VALUES (2,'Nowak','Anna', 1600, '2012-01-01',2) SELECT * FROM Pracownicy

Jak sprawdzić największą wartość w kolumnie IDENTITY, albo ostatnio wygenerowaną wartość w bieżącej sesji? Odpowiedź na przykładach. DROP TABLE TestIdentity GO CREATE TABLE TestIdentity(k1 INT IDENTITY(1,1) PRIMARY KEY, K2 INT) INSERT INTO TestIdentity VALUES(100),(200),(300) GO SELECT * FROM TestIdentity DBCC CHECKIDENT (TestIdentity) DBCC CHECKIDENT (TestIdentity, RESEED, 2) DBCC CHECKIDENT (TestIdentity) INSERT INTO TestIdentity VALUES(400) -- wprowadzi nowy rekord z wartością 4(!) w kolumnie k1 SELECT * FROM TestIdentity DBCC CHECKIDENT (TestIdentity)

DROP TABLE TestIdentity2 GO CREATE TABLE TestIdentity2(k1 INT IDENTITY(1,1) PRIMARY KEY, K2 INT) GO INSERT INTO TestIdentity2 VALUES(100),(200) SELECT * FROM TestIdentity2 SELECT SCOPE_IDENTITY() -- ostatnio wygenerowana wartość w bieżącej sesji = 2 SELECT @@IDENTITY -- to samo SELECT IDENT_CURRENT('TestIdentity') -- ostatnia wartość w tabeli wprowadzona przez dowolną sesję (4) SELECT IDENT_CURRENT('TestIdentity2') -- ostatnia wartość w tabeli wprowadzona przez dowolną sesję (2) DELETE FROM TestIdentity DBCC CHECKIDENT (TestIdentity) INSERT INTO TestIdentity VALUES(100) -- do k1 wpisana będzie wartość 5 SELECT * FROM TestIdentity DBCC CHECKIDENT (TestIdentity) DELETE FROM TestIdentity -- lub TRUNCATE TABLE TestIdentity DBCC CHECKIDENT (TestIdentity, RESEED, 0) DBCC CHECKIDENT (TestIdentity) INSERT INTO TestIdentity VALUES(100) ---- do k1 wpisana będzie wartość 1 SELECT * FROM TestIdentity SELECT SCOPE_IDENTITY() -- wypisze 1 SELECT IDENT_CURRENT('TestIdentity') -- wypisze 1 SELECT IDENT_CURRENT('TestIdentity2') -- wypisze 2

Automatyczne numerowanie – sekwencje (dostępne w wielu systemach). DROP SEQUENCE NumeryPracownikow CREATE SEQUENCE dbo.NumeryPracownikow AS INT START WITH 1 DROP TABLE Pracownicy --Pobranie nowej wartości z sekwencji: NEXT VALUE FOR NumeryPracownikow --Można tę wartość wyświetlić: SELECT NEXT VALUE FOR NumeryPracownikow

Wartości domyślne - DEFAULT CREATE TABLE Pracownicy( Nr INT PRIMARY KEY DEFAULT NEXT VALUE FOR NumeryPracownikow, Nazwisko NVARCHAR(50) NOT NULL, Imie NVARCHAR(50) NOT NULL, Stawka MONEY DEFAULT 1500, DataZatrudnienia DATE DEFAULT NULL, LiczbaDzieci TINYINT DEFAULT 0 ) INSERT INTO Pracownicy(Nazwisko,Imie) VALUES ('Wrona','Adam') SELECT * FROM Pracownicy

Do kolumny z ustawioną własnością DEFAULT na pobieranie nowych wartości z sekwencji można wprowadzać samemu dane, jednak może to rodzić problemy z wstawianiem kolejnych wierszy, dla których numery będą pochodzić z sekwencji. INSERT INTO Pracownicy VALUES (2,'Nowak','Anna', 1600, '2012-01-01',2) --Tu pojawi się problem: wiersz zostanie odrzucony z powodu powtórzenia --wartości w kolumnie klucza głównego INSERT INTO Pracownicy(Nazwisko,Imie,Stawka,DataZatrudnienia, LiczbaDzieci) VALUES ('Wrona','Adam', 1100, '2015-01-01',2) --Można pobrać nową wartość z sekwencji, chociaż nie jest to konieczne, ponieważ --poprzednie nieudane zdanie Insert spowodowało już pobranie wartości 2 --a kolejną będzie 3 SELECT NEXT VALUE FOR NumeryPracownikow INSERT INTO Pracownicy(Nazwisko,Imie,Stawka,DataZatrudnienia, LiczbaDzieci) VALUES ('Wrona','Adam', 1100, '2015-01-01',2) SELECT *

FROM Pracownicy

Modyfikacja sekwencji (RESTART): CREATE SEQUENCE dbo.TestSequence AS INT START WITH 1 ALTER SEQUENCE dbo.TestSequence RESTART WITH 1 SELECT NEXT VALUE FOR dbo.TestSequence SELECT NEXT VALUE FOR dbo.TestSequence SELECT NEXT VALUE FOR dbo.TestSequence

Sprawdzenie bieżącej wartości w sekwencji: SELECT current_value FROM sys.sequences WHERE name = 'TestSequence'

Atomowość pojedynczych instrukcji w Transact SQL. W systemie Microsoft SQL Server w jednym zdaniu INSERT można wprowadzić więcej niż jeden wiersz. Jest to rozwiązanie nietypowe. DELETE FROM Pracownicy INSERT INTO Pracownicy VALUES (1,'Kowal','Piotr', 1500,'2010-01-01',2), (2,'Nowak','Anna', 1600,'2012-01-01',1), (3,'Wrona','Adam', 1100,'2015-01-01',2) SELECT * FROM Pracownicy

Włączenie trybu niezliczania wierszy SET NOCOUNT ON DELETE FROM Pracownicy INSERT INTO Pracownicy VALUES (1,'Kowal','Piotr', 1500,'2010-01-01',2), (2,'Nowak','Anna', 1600,'2012-01-01',1), (3,'Wrona','Adam', 1100,'2015-01-01',2)

Wyłączenie (powrót do domyślnego trybu zliczania wierszy): SET NOCOUNT OFF

Domyślnie w systemie Microsoft SQL Server jedna instrukcja operująca na danych jest traktowana jako pojedyncza transakcja, która jest albo w całości zatwierdzana, albo w całości odrzucana. DELETE FROM Pracownicy SELECT * FROM Pracownicy --Poniższa instrukcja nie wprowadzi do tabeli żadnego wiersza, ponieważ w trzecim --jest naruszenie klucza głównego (duplikat wartości 1). INSERT INTO Pracownicy VALUES (1,'Kowal','Piotr', 1500,'2010-01-01',2), (2,'Nowak','Anna', 1600,'2012-01-01',1), (1,'Wrona','Adam', 1100,'2015-01-01',2) SELECT * FROM Pracownicy INSERT INTO Pracownicy VALUES (1,'Kowal','Piotr', 1500,'2010-01-01',2), (2,'Nowak','Anna', 1600,'2012-01-01',1), (3,'Wrona','Adam', 1100,'2015-01-01',2) SELECT * FROM Pracownicy

Klucz główny złożony z kilku kolumn --Poniższy pomysł na klucz główny w tabeli Urlopy nie jest dobry! --Jeśli tak zrobimy, to każdy pracownik mógłby mieć co najwyżej jeden urlop. --Próba wprowadzenie drugiego urlopu dla pracownika np. nr 1 zakończy się --niepowodzeniem z powodu duplikatu w kluczu głównym CREATE TABLE Urlopy( NrPrac INT PRIMARY KEY, OdKiedy DATE, DoKiedy DATE ) INSERT INTO Urlopy VALUES(1,'2015-01-01','2015-01-23') SELECT * FROM Urlopy INSERT INTO Urlopy VALUES(1,'2015-04-01','2015-01-4') DROP TABLE Pracownicy --Klucz główny może się składać z dwóch kolumn. --Jednak tak jak w poniższym przykładzie nie można tworzyć klucza złożonego. --System potraktuje to jako próbę utworzenia dwóch kluczy głównych i wyświetli --komunikat o błędzie. CREATE TABLE Urlopy( NrPrac INT PRIMARY KEY, OdKiedy DATE PRIMARY KEY, DoKiedy DATE ) DROP TABLE Urlopy --Rozwiązanie poprawne: CREATE TABLE Urlopy( NrPrac INT, OdKiedy DATE, DoKiedy DATE, PRIMARY KEY(Nrprac,OdKiedy) ) --Można byłoby też tak: CREATE TABLE Urlopy( NrPrac INT, OdKiedy DATE, DoKiedy DATE) ALTER TABLE Urlopy ADD PRIMARY KEY(NrPrac, OdKiedy) SELECT * FROM Urlopy

Więzy klucza obcego – Foreign Key (FK) --Przed włączeniem więzów klucza obcego można wpisać do tabeli Urlopy --urlop dla nieistniejącego pracownika np. o numerze 23416: INSERT INTO Urlopy VALUES (23416,'2015-01-01','2015-01-05') SELECT * FROM Urlopy

--Przydałoby się jeszcze włączyć odpowiedni warunek CHECK, dotyczący --dat rozpoczęcia i zakończenia urlopu: ALTER TABLE Urlopy ADD CHECK (DoKiedy >= OdKiedy) DELETE FROM Urlopy --Włączenie więzów klucza obcego (dodanie klucza obcego) w tabeli Urlopy ALTER TABLE Urlopy ADD FOREIGN KEY (NrPrac) REFERENCES Pracownicy(Nr) --Teraz nie da się wpisać urlopu dla pracownika o numerze 23416, -- ponieważ w tabeli Pracownicy są tylko dane pracowników o numerach 1,2 i 3. INSERT INTO Urlopy VALUES (23416,'2015-01-01','2015-01-05') --To się uda: INSERT INTO Urlopy VALUES (1,'2015-01-01','2015-01-05') --To też się uda: INSERT INTO Urlopy VALUES (3,'2015-01-01','2015-01-05') --To się nie uda, ponieważ próbuje się wposać duplikat do kolumny klucza głównego. --Para Nr i OdKiedy się powtarza: INSERT INTO Urlopy VALUES (1,'2015-01-01','2015-01-20') --To się uda. Oczywiście w kolumnie klucza obcego konkretne wartości mogą się --powtarzać wielokrotnie. Pracownik numer 1 może mieć wiele urlopów. Nie może jednak --mieć dwóch urlopów zaczynających się od tego samego dnia, bo to stanowiłoby --naruszenie warunku unikalności klucza głównego. INSERT INTO Urlopy VALUES (1,'2015-02-01','2015-02-07') SELECT * FROM Urlopy SELECT * FROM Pracownicy --To się nie uda: DELETE FROM Pracownicy WHERE Nr=1

Po włączeniu więzów klucza obcego (czyli po zdefiniowaniu klucza obcego) system będzie blokował wszystkie operacje, które zakończyłyby się tym, że w kolumnie klucza obcego będzie wartość, której nie ma w kluczu głównym tabeli, do której się klucz obcy odwołuje (REFERENCES). --To się uda, ponieważ pracownik numer 2 nie ma żadnego urlopu. --Liczba 2 nie występuje w kolumnie klucza obcego w tabeli Urlopy. DELETE FROM Pracownicy WHERE Nr=2 SELECT * FROM Pracownicy --Wprowadźmy dane pani Nowak jeszcze raz. --DYGRESJA - W SQL Serwerze można pominąć słowo INTO w zdaniu INSERT --Lepiej jednak się do tego nie przyzwyczajać, ponieważ w innych systemach --słowo INTO jest obowiązkowe.

INSERT Pracownicy VALUES (2,'Nowak','Anna', 1600,'2012-01-01',1) SELECT * FROM Pracownicy

Aktualizacja wierszy – zdanie UPDATE (podstawy). UPDATE Pracownicy SET Stawka = Stawka*1.10, LiczbaDzieci=3 WHERE Nr=1 SELECT * FROM Pracownicy UPDATE Pracownicy SET Stawka = Stawka*1.10, LiczbaDzieci=3 WHERE Nr=15 --Ciekawostka – w języku SQL tak można zamienić wartości w kolumnach. --Dane z kolumny Imię zostaną wpisane do kolumny Nazwisko, a dane z kolumny Nazwisko --(czyli nazwisko pracownika) zostanie wpisane do kolumny Imię. UPDATE Pracownicy SET Nazwisko=Imie, Imie=Nazwisko WHERE Nr=1 SELECT * FROM Pracownicy --Wróćmy z powrotem do poprawnych danych (zamieńmy imiona z nazwiskami jeszcze raz): UPDATE Pracownicy SET Nazwisko=Imie, Imie=Nazwisko WHERE Nr=1 SELECT * FROM Pracownicy SELECT * FROM Urlopy --Zmiana numeru pracownika z 3 na 2 w jedynym urlopie pracownika numer 3 --się uda, ponieważ liczba 2 występuje w tabeli Pracownicy i poniższe zdanie --nie spowoduje naruszenia klucza obcego: UPDATE Urlopy SET NrPrac=2 WHERE Nrprac=3 --Powyższą zmianę można uzasadnić na przykład pomyłką – omyłkowo wpisaliśmy --urlop pracownikowi numer 3 a powinniśmy wpisać ten urlop pracownikowi numer 2. --Oczywiście taka poprawa musi być możliwa. --Uwaga – w zdaniu UPDATE kierowanym do tabeli Urlopy w warunku WHERE --na ogół powinno się odwoływać do obydwu kolumn klucza głównego: NrPrac i OdKiedy. --W powyższym przykładzie tak nie jest, bo jest tylko jeden wiersz w tabeli Urlopy -- z numerem pracownika 3.

SELECT * FROM Urlopy --Taka zmiana się NIE uda, bo nie ma pracownika numer 2512 UPDATE Urlopy SET NrPrac=2512 WHERE Nrprac=2 SELECT * FROM Urlopy

--Przywróćmy z powrotem urlop pracownikowi numer 3: UPDATE Urlopy SET NrPrac=3 WHERE Nrprac=2 SELECT * FROM Urlopy SELECT * FROM Pracownicy --Zmiana numeru pracownika z 1 na 120 się nie uda, ponieważ --liczba 1 występuje w kolumnie klucza obcego w tabeli Urlopy --(pracownik numer 1 ma co najmniej jeden urlop) UPDATE Pracownicy SET Nr = 120 WHERE Nr = 1 --Jak widać zdefiniowanie klucza głównego w tabeli Urlopy spowodowało, że --system blokuje pewne operacje w tabeli Pracownicy! --Gdyby powyższa zmiana się udała, to wszystkie urlopy z NrPrac równym 1 byłyby --niepoprawne, bo takiego pracownika by nie było (zmieniliśmy mu numer). SELECT * FROM Pracownicy

--Jednak poniższa zmiana się uda, ponieważ pracownik numer 2 nie ma jeszcze --żadnego urlopu i zmiana numeru w tabeli Pracownicy nie spowoduje naruszenia --klucza obcego w tabeli Urlopy. UPDATE Pracownicy SET Nr = 227 WHERE Nr = 2 SELECT * FROM Pracownicy

Akcje kaskadowe dla więzów klucza obcego. ALTER TABLE Urlopy DROP CONSTRAINT [FK__Urlopy__NrPrac__2A164134] ALTER TABLE Urlopy ADD FOREIGN KEY (NrPrac) REFERENCES Pracownicy (Nr) ON DELETE CASCADE ON UPDATE CASCADE SELECT * FROM Pracownicy SELECT * FROM Urlopy Włączenie kaskadowych akcji spowoduje, że da się kasować dowolne wiersze w tabeli Pracownicy, jednak pociągnie to za sobą kaskadowe kasowanie wszystkich urlopów skasowanych pracowników tak, by w tabeli Urlopy w kolumnie klucza obcego nie było niepoprawnych wartości. DELETE FROM pracownicy WHERE Nr=1 SELECT * FROM Pracownicy SELECT * FROM Urlopy Podobnie da się zmieniać numery pracowników, spowoduje to kaskadową zmianę w tabeli Urlopy. UPDATE Pracownicy SET Nr=333

WHERE Nr=3 SELECT * FROM Pracownicy SELECT * FROM Urlopy --Klucz obcy można definiować też podczas tworzenia tabeli DROP TABLE Urlopy CREATE TABLE Urlopy( NrPrac INT REFERENCES Pracownicy(Nr), OdKiedy DATE, DoKi...


Similar Free PDFs