go backsqlschool blogs list

Do not uncheck “Prevent saving changes that require table re-creation” option on SSMS

by Antonios Chatzipavlis

Οι περισσότεροι από εσάς όταν θέλετε να αλλάξετε την δομή ενός πίνακα σε μια βάση χρησιμοποιείτε το SQL Server Management Studio (SSMS) όπου με δεξί κλικ στον πίνακα κάνετε design και αφού κάνετε την αλλαγή που θέλετε πατάτε το save button από την toolbar.

Είμαι σίγουρος έχετε κάνει πολλά πράγματα  έτσι και έχετε μείνει απόλυτα ευχαριστημένοι. Θεωρώ επίσης βέβαιο ότι κάποια στιγμή που κάτι πάλι θέλατε να αλλάξετε αυτό δεν μπορούσε να γίνει καθώς ο SSMS σας εμφάνισε ένα παράθυρο όπως το παρακάτω.

img

Είμαι παραπάνω από σίγουρος ότι το πρώτο πράγμα που κάνετε είναι να πάτε σε μία μηχανή αναζήτησης και ψάξατε για το μήνυμα που το παράθυρο σας έλεγε.

Το internet είναι ευχή και κατάρα ταυτόχρονα. Ευχή γιατί μπορείς να βρεις ότι θες αλλά γίνεται κατάρα όταν αυτά που βρίσκουμε τα καταναλώνουμε αμάσητα. Για αυτό το λόγο συμβουλεύω όλους σας πριν καταφύγετε στις μηχανές αναζήτησης διαβάστε το documentation του προϊόντος ή τουλάχιστον ρωτήστε κάποιον που κατέχει καλά το προϊόν.

Σίγουρα μέσα στα πρώτα αποτελέσματα που σας έβγαλε η μηχανή αναζήτησης θα βρήκατε πολλές αναφορές για το συγκεκριμένο θέμα και οι περισσότερες αναφορές έδιναν την ίδια συμβουλή, την οποία και ακολουθήσατε τυφλά μιας και το έλεγαν πολλοί και η οποία φυσικά σας έπαιξε. Ίσως μάλιστα κάποιοι από εσάς την βρήκατε αρκετά χρήσιμη συμβουλή και σε όσους SQL Server πάτε φροντίζετε να την ακολουθείτε.

Η συγκεκριμένη συμβουλή σας προέτρεπε να πάτε στην SSMS menu Tools>Options και στο Option window να επιλέξετε Designers και να κάνετε uncheck το option που λέει “Prevent saving changes that require table re-creation”.

image

Αρκετοί ίσως να εκφράσατε την άποψη ότι αυτό θα έπρεπε να είναι το default και ότι για ακόμα μια φορά η κατασκευάστρια εταιρεία έκανε λάθος επιλογή.

Ελάχιστοι ίσως να μπήκατε στον πειρασμό να δείτε τα Books Online για το τι προσπαθεί να κάνει το συγκεκριμένο option. Για το λόγο αυτό σας παραθέτω ακριβώς το συγκεκριμένο τμήμα από τα BOL

Prevents a user from making changes that require re-creating the table. The following actions might require a table to be re-created:

  • Adding a new column to the middle of the table
  • Dropping a column
  • Changing column nullability
  • Changing the order of the columns
  • Changing the data type of a column


Αν δεν το καταλάβατε να σας το εξηγήσω λίγο καλύτερα. 

Αν μέσα από τα σχεδιαστικά εργαλεία κάνετε μια από τις εργασίες που αναφέρονται σε ένα πίνακα τότε ο πίνακας θα γίνει drop και create ξανά.

Αυτό ο SQL Server το υλοποιεί με το να δημιουργήσει ένα πίνακα που σαν όνομα έχει το tmp_<orginal table name> και το οποίο είναι σύμφωνο με τις αλλαγές που ζητήθηκαν. Κατόπιν στο original table σβήνει όλα τα constraints και μεταφέρει όλα τα δεδομένα του στον νέο πίνακα που έχει φτιάξει και αυτό το κάνει με απλό T-SQL. Αφού τελειώσει αυτό σβήνει τον original πίνακα και κάνει rename τον πίνακα με το tmp prefix στο όνομα του orginal. Τέλος δημιουργεί ξανά τα constraints.

Αυτό σε ένα παραγωγικό περιβάλλον με πολλές χιλιάδες εγγραφές θα πάρει ώρα ή και ώρες πράγμα που σημαίνει ότι δεν θα είναι διαθέσιμος ο πίνακας στους χρήστες και είναι πραγματικός εφιάλτης πιστέψτε με.

Έχοντας αυτό το option ενεργοποιημένο σε σώζει από αυτόν τον εφιάλτη και συνιστώ ανεπιφύλακτα να μην απενεργοποιηθεί για κανέναν λόγο σε περιβάλλον παραγωγής.

Είμαι λίγο ελαστικός για περιβάλλον ανάπτυξης μόνο όταν αυτό δεν είναι κοινό σε πολλούς developers (έχει ο κάθε dev το δικό του instance). Άλλα αυτό που πραγματικά προτείνω είναι ακόμα και σε τέτοιο περιβάλλον να μην αλλάζει για κανένα λόγο γιατί έτσι δεν θα μάθετε να το κάνετε με άλλον τρόπο.

Στο σημείο αυτό θα πρέπει να επισημανθεί ότι όλοι οι designer έχουν ένα button με το οποίο μπορείτε να δείτε το t-sql script το οποίο και θα χρησιμοποιηθεί και το οποίο μπορείτε να χρησιμοποιήσετε και σαν εργαλείο εκμάθησης διότι κανένας μας δεν έχει πάθει τίποτα με το να γνωρίζει καλά την T-SQL.

Ειδικά για τον table designer είναι αυτό που είναι σε κύκλο στην παρακάτω εικόνα.

image

Για όσους τώρα αναρωτιούνται τι θα πρέπει να κάνουν στις περιπτώσεις που αναφέρονται στα BOL σχετικά με το συγκεκριμένο option απαντώ ξεκάθαρα για το κάθε ένα

1. Adding a new column to the middle of the table

Δεν υπάρχει κανένας λόγος να κάνετε κάτι τέτοιο. Αν πιστεύετε ότι τα δεδομένα στο πίνακα αποθηκεύονται όπως έχετε ορίσει την σειρά των πεδίων πάνω σε αυτόν, να σας ενημερώσω ότι αυτό δεν γίνεται (το έχω αναφέρει πολλές φορές το πώς αποθηκεύονται στο παρελθόν).
Αν τώρα θέλατε να κάνετε αυτό για να έρχονται σε ένα SELECT * query με την σειρά που επιθυμείτε. Χρόνια το φωνάζω ότι δεν είναι καλό να χρησιμοποιείτε *. Φτιάξετε το query σας και βάλτε τα πεδία με όποια σειρά εσείς θέλετε. Δεν θέλετε να το κάνετε συνέχεια;  Βάλτε αυτό το query σε ένα view. Λύσεις υπάρχουν.


2. Dropping a column

Το να σβήσεις μια κολόνα από ένα πίνακα είναι πραγματικά το ποιο εύκολο και γρήγορο πράγμα ακόμα και αν αυτή χρησιμοποιείται σαν index ή constraint. Από την άλλη πάλι και πριν σβήσετε την κολόνα θα πρέπει να δείτε που αυτή χρησιμοποιείται για να διασφαλίσετε ότι δεν θα χτυπήσει κάτι άλλο. Αυτό δεν το κάνει το η διαδικασία που περιέγραψα παραπάνω.

3. Changing column nullability

Ισχύουν όλα όσα αναφέρονται στο 5.


4. Changing the order of the columns

Ισχύουν όλα όσα αναφέρονται στο 1.

5. Changing the data type of a column

Αν θέλετε να κάνετε κάτι τέτοιο θα πρέπει πρώτα να γνωρίζετε τις εξαρτήσεις που υπάρχουν με άλλα objects και μετά να προχωρήσετε σε αυτό. Η διαδικασία είναι απλούστερη και σαφώς καλύτερη από το drop & recreation του πίνακα.
Φτιάξετε την νέα κολόνα όπως την θέλετε με ένα προσωρινό όνομα και με ένα απλό και συνήθως γρήγορο update statement ενημερώστε την με τα δεδομένα της υπάρχουσας, σβήστε την παλιά κολώνα και κάντε rename την νέα που φτιάξατε στο όνομα της παλιάς. Είναι τόσο απλό και γρήγορο.


Enjoy it!

/*antonch*/


Ημερομηνία: 04 December 2014 18:48
Share it:

Σχόλια - Comments

user-gravatar

Στις 04 Dec 2014 @ 7:17 PM o/η George J. Capnias έγραψε:

Είσαι κακός άνθρωπος - προσπαθείς να αφαιρέσεις όλη τη διασκέδαση που μπορεί να έχει κάποιος! Και φυσικά αφήνεις τον wanna-be-dba να κάνει αυτόματα το drop/recreate του πίνακα επάνω στο production περιβάλλον - μην σου πω, ότι όταν καθυστερεί, τον προτρέπεις να κάνει και break το operation για να εξασφαλίσεις ότι η βάση δεν θα είναι usable στην συνέχεια...

user-gravatar

Στις 04 Dec 2014 @ 7:29 PM o/η Ζαχαρίας Δεντοφτιάχνω έγραψε:

Τι να εννοεί άραγε...Εμένα πάντως την τελευταία φορά που ο Ψηλομύτης Μεμάστερ αποφάσισε να κάνει κατι τέτοιο στο production, προκειμένου να αλλάξει ένα πεδίο nvarchar(200) σε nvarchar(201) έκανε τα εξής:- Δεξι κλικ - All tasks - Generate Scripts (Schema and Data) - DROP την production database και δημιουργία νέας (γλυτώνουμε και τα logs)- Upload ta scripts και εκτέλεση.Ε, από το να μην είναι usable ένα table, καλύτερα να μην είναι usable ΟΛΗ η db για μερικές ώρες. Να αποφύγουμε σφάλματα. Οκ, το script τελικά εστάλη με courier overnight σε πέντε δίσκους που τους κόλλησαν πάνω στο server γιατί ήταν λίγο μεγάλο, αλλά έγινε η δουλειά.

user-gravatar

Στις 05 Dec 2014 @ 12:50 AM o/η johnbaos έγραψε:

Σε μερικές περιπτώσεις είναι ευκολία , σε άλλες χρειάζεται script, ανάλογα την γνώση που έχεις πάνω στα dependencies της βάσης που αλλάζεις.

Αφήστε το σχόλιο σας - Leave your comment

Τα σχόλια έχουν κλείσει.
Επιτρέπονται μόνο τα σχόλια από τα μέλη του SqlSchool.gr.


newsletter subscription

Εάν επιθυμείτε να λαμβάνετε ενημέρωση από εμάς, δώστε μας το e-mail σας.
PASS chapter logo
Official Professional Association for SQL Server (PASS) chapter for Greece
Join to PASS