Αφού είδαμε στο προηγούμενο post αυτής της σειράς πώς φτιάχνουμε την βάση και τους πίνακές μας, σε αυτό το post θα βάλουμε δεδομένα σε αυτούς τους πίνακες και θα δούμε τα DML statements. Αυτά τα statements είναι τα εξής:
- INSERT, για να προσθέσουμε εγγραφές σε έναν πίνακα.
- SELECT, για να πάρουμε τα δεδομένα από τους πίνακές μας
- UPDATE, για να τροποποιήσουμε τις εγγραφές μας
- DELETE, για να διαγράψουμε εγγραφές
Έχοντας δημιουργήσει τη βάση και τους πίνακες μας, θέλουμε αρχικά να βάλουμε δεδομένα σε αυτούς. Πρώτα θα εισάγουμε συγγραφείς και κατηγορίες. Ξεκινάμε από αυτά, διότι απαιτείται για ένα βιβλίο που θα θελήσουμε να εισάγουμε στον πίνακα Books να υπάρχει η αντίστοιχη εγγραφή για το είδος του και τον συγγραφέα του στους πίνακες Genres και Authors. Η απαίτηση αυτή προκύπτει από τα foreign key constraints που έχουμε στον πίνακα Books και από το ότι οι στήλες GenreId και AuthorId δεν επιτρέπεται να έχουν NULL τιμές.
Η εισαγωγή των δεδομένων επιτυγχάνεται με τα παρακάτω insert statements, ενώ στην συνέχεια βλέπουμε τα δύο select statements με τα οποία μπορούμε να δούμε τα δεδομένα που έχουν μετα την εισαγωγή οι πίνακες μας.
USE BookCave;
GO
-- Insert Authors
INSERT INTO Authors (Firstname,Lastname) VALUES (N'STEPHEN',N'KING');
INSERT INTO Authors (Firstname,Lastname) VALUES (N'KEN',N'FOLLETT');
INSERT INTO Authors (Firstname,Lastname) VALUES (N'STIEG',N'LARSSON');
-- Insert Genres
INSERT INTO Genres (Description) VALUES
(N'HORROR'),
(N'HISTORICAL NOVELS'),
(N'CRIME FICTION');
GO
SELECT * FROM Authors;
SELECT * FROM Genres;
GO
Το αποτέλεσμα των select statements είναι το παρακάτω:
Η προσθήκη των δεδομένων στον πίνακα των βιβλίων καθώς και το SELECT statement με το οποίο θα δούμε τα περιεχόμενα του πίνακα μετά την εισαγωγή αυτή έχουν ως εξής:
-- Insert Books
INSERT INTO Books (Title,AuthorId,GenreId,MainLanguage)VALUES
(N'IT',1,1,'EN'),
(N'MISERY',1,3,'EN'),
(N'Η ΛΑΜΨΗ',1,1,'GR'),
(N'PILLARS OF THE EARTH',2,2,'EN'),
(N'WORLD WITHOUT END',2,2,'EN'),
(N'THE GIRL WITH THE DRAGON TATTOO',3,3,'EN');
GO
SELECT * FROM Books;
GO
Και το αποτέλεσμα:
Παρατηρώντας τώρα τι είναι αυτό που τρέξαμε, θα πρέπει να σταθούμε στα εξής:
- Στα INSERT statements αναφέρουμε τις στήλες στις οποίες θα βάλουμε τιμές και με την ίδια σειρά τις τιμές αυτών.
- Στις παραπάνω περιπτώσεις δεν ορίσαμε στο INSERT statement τιμή για την στήλη ID καθώς αυτή θα πάρει αυτόματα την τιμή της μέσω του IDENTITY.
- Για να επιτύχει το INSERT που επιχειρούμε να κάνουμε προσέχουμε να δώσουμε τιμή για όλες τις στήλες που έχουν ορισθεί με NOT NULL, δεν είναι IDENTITY και δεν έχουμε ορίσει DEFAULT τιμή για αυτές.
- Στην περίπτωση των συγγραφέων, προσθέσαμε μια μία τις εγγραφές, με ένα ξεχωριστό insert για κάθε μία, ενώ στις άλλες δύο περιπτώσεις προστέθηκαν όλες μαζί στον πίνακα, με μια μόνο εντολή insert.
- Στα strings βλέπουμε ένα N μπροστά, το οποίο ορίζει ότι αυτές οι τιμές που δίνουμε είναι Unicode strings, ταιριάζοντας με τον τύπο nvarchar που έχουμε ορίσει τις στήλες μας.
-
Θα πρέπει να προσέξουμε οι τιμές των strings που δίνουμε να μην ξεπερνάνε τους
maximum
χαρακτήρες που ορίσαμε για την κάθε στήλη. Σε διαφορετική περίπτωση, ένα
error
θα εμποδίσει το
insert
που θα προσπαθήσουμε να κάνουμε. Για παράδειγμα, αν η στήλη του τίτλου είχε ορισθεί με τύπο
nvarchar(60)
αντί για
nvarchar(150)
και προσπαθούσαμε να εισάγουμε το παρακάτω βιβλίο:
INSERT INTO Books (Title,AuthorId,GenreId,MainLanguage)VALUES
(N'AND HERE IS A VERY LARGE TITLE FOR A RANDOM BOOK THAT SHOULD FAIL INSERT',1,1,'EN');
το αποτέλεμα θα ήταν το
error:
“
String or binary data would be truncated. The statement has been terminated.
”
και η εγγραφή αυτή δεν θα προστεθεί στον πίνακα των βιβλίων.
Αφού έχουμε βάλει και μπορούμε να δούμε τα δεδομένα στους πίνακες, ήρθε η ώρα να δούμε τι κάνουμε αν θέλουμε να μεταβάλλουμε τις τιμές τους. Και αυτό τον σκοπό έχει το UPDATE statement. Έστω λοιπόν ότι το βιβλίο “World Without End” το βιβλιοπωλείο μας το πουλάει στα ελληνικά και όχι στα αγγλικά όπως δηλώσαμε εμείς. Με το παρακάτω UPDATE ζητάμε να αλλάξει η τιμή της στήλης MainLanguage σε GR για τις εγγραφές που το Id έχει τιμή 5. Στην συνέχεια επιλέγουμε να δούμε αυτή την συγκεκριμένη εγγραφή για να βεβαιωθούμε ότι η τιμή άλλαξε όπως θέλαμε.
UPDATE Books
SET MainLanguage = 'GR'
WHERE Id = 5;
GO
SELECT *
FROM Books
WHERE Id = 5;
GO
Το where clause και στα δύο παραπάνω statements, λειτουργεί ως φίλτρο στις εγγραφές. Δηλαδή στην πρώτη περίπτωση μεταβάλλονται και στην δεύτερη μας επιστρέφονται σαν αποτέλεσμα μόνο οι εγγραφές για τις οποίες ικανοποιείται η συνθήκη που ορίζεται στο where clause. Φυσικά, στο παραπάνω παράδειγμα η εγγραφή είναι μια και μοναδική, καθώς η στήλη Id είναι το PRIMARY KEY.
Αυτό όμως δεν σημαίνει πως δεν μπορούμε να μεταβάλλουμε πολλές εγγραφές με ένα update. Για παράδειγμα με την παρακάτω εντολή θα αλλάζαν οι τέσσερεις εγγραφές που αντιστοιχούν σε βιβλία με κύρια γλώσσα την αγγλική και θα αποκτούσαν κύρια γλώσσα την ελληνική:
UPDATE Books
SET MainLanguage = 'GR'
WHERE MainLanguage = 'EN';
Τέλος για να διαγράψουμε εγγραφές, θα χρησιμοποιήσουμε το DELETE. Για παράδειγμα αν θέλουμε να διαγράψουμε το βιβλίο που αλλάξαμε προηγουμένως αντίστοιχα θα έπρεπε να τρέξουμε το εξής:
DELETE BOOKS
WHERE Id = 5;
Για να διαγράψουμε όλα τα βιβλία ενός συγγραφέα μπορούμε να γράψουμε το εξής:
DELETE Books
WHERE AuthorId = 1;
διαγράφοντας τις 3 εγγραφές για τις οποίες ισχύει αυτή η συνθήκη.
Πρέπει να σημειωθούν τα εξής:
- Αν παραλείψουμε το where clause στο update ή το delete τότε επηρεάζουν όλες τις εγγραφές του πίνακα. Δηλαδή, το “UPDATE BOOKS SET GenreId = 1” θα βάλει όλα τα βιβλία στην κατηγορία Horror, ενώ το “DELETE Books” θα σβήσει όλο τον πίνακα των βιβλίων.
- Αν προσπαθούσαμε να διαγράψουμε εγγραφή από τον πίνακα Genres, θα αποτυγχάναμε λόγω των foreign key constraints του πίνακα Books. Με άλλα λόγια όσο υπάρχει βιβλίο ενός είδους στον πίνακα Books, το είδος αυτό δεν μπορεί να διαγραφεί από τον πίνακα Genres. Αντίστοιχος περιορισμός υπάρχει και για τους συγγραφείς.
- Το παραπάνω δεν ισχύει στην περίπτωση που στο foreign key constraint, δηλαδή στο παράδειγμά μας το FK_Books_Genres, είχε ορισθεί να γίνεται cascade on delete. Σε αυτή την περίπτωση το “DELETE Genres WHERE Id = 3;” θα είχε ως αποτέλεσμα τη διαγραφή του είδους Horror, αλλά και τη διαγραφή των βιβλίων αυτού του είδους. Αντίστοιχα και για το UPDATE των ids των συγγραφέων και των ειδών.