go backsqlschool blogs list

SOME T-SQL IMPLICIT CASTING TRAPS

by Fivi Panopoulou

Θα ξεκινήσω με το disclaimer. Είναι γνωστό ότι τα implicit casts κρύβουν κινδύνους και ειδικά μέσα στα queries μας τα αποφεύγουμε. Παρόλα αυτά είναι καλό να ξέρουμε πως συμπεριφέρονται στον SQL Server και τι να περιμένουμε στο αποτέλεσμα.

Σε αυτό το post λοιπόν θα δούμε κάποιες περιπτώσεις που μπορεί να διαφύγουν σε κάποιον, να αποτελούν misconceptions ή κάποιος να περιμένει διαφορετική συμπεριφορά ειδικά αν σκέφτεται σε άλλη γλώσσα.

Για αρχή λοιπόν πρέπει κανείς να έχει στον νου του το data type precedence, το οποίο βρίσκει εδώ και μας δείχνει ποιος τύπος υπερισχύει όταν ένας operator προσπαθεί να συνδυάσει expressions διαφορετικού τύπου.

1) Numbers and strings

Αυτό που θα ήθελα να τονίσω και αποτελεί την πιο εύκολη πηγή λάθους είναι το πόσο κάτω πρέπει να σκρολλάρει κανείς τη λίστα για να φτάσει στους τύπους nvarchar, nchar, varchar, char. Αυτό σημαίνει ότι η πλειονότητα των άλλων τύπων, όταν συνδυάζεται με character string types θα υπερισχύσει.

Για παράδειγμα το expression 12 + '3' δεν θα μας δώσει error ούτε θα επιστρέψει το string '123', αλλά θα επιστρέψει τον int 15. Αν ο δεύτερος operand δεν μετατρέπεται σε int πχ 12 + '3asdf' θα έχουμε error. Επίσης ο τύπος που υπερισχύει δεν έχει να κάνει ποτέ με την σειρά που εμφανίζονται, δηλαδή το '12' + 3 θα κάνει επίσης 15

Το ίδιο ισχύει για όλους τους τύπους που είναι πάνω από το nvarchar.

2) NULL, ISNULL και COALESCE

Πριν από όλα θα ξεκαθαρίσω καλού κακού το εξής: το SELECT CAST(NULL as int) μας δίνει NULL, όπως και όταν έχουμε κάνει declare int variable που δεν έχει γίνει πουθενά initialize είναι NULL (όχι 0).

Από την άλλη τo SELECT CAST('' as int) δίνει 0 (όχι error, όχι null). H ISNULL συνάρτηση κοιτάει τον τύπο του πρώτου ορίσματος και αυτός θα είναι και το αποτέλεσμά της. Επομένως αν έχω το παρακάτω κομμάτι:

DECLARE @X int;
SELECTas X, ISNULL(@X,'') as Y;

Θα μου δώσει:

X Y
NULL 0

Και μιας που πιάσαμε το ISNULL θα ήθελα να επισημάνω την διαφορά που έχει από το COALESCE όταν δίνουμε ορίσματα διαφορετικού τύπου.
Παρακάτω βλέπουμε ότι για τα ίδια ορίσματα έχουμε διαφορετικό τύπου αποτέλεσμα:

DECLARE @X nvarchar(10) = NULL;

SELECT ISNULL(@X,42) as IsNullRes, 
COALESCE(@X,42) as CoalesceRes
INTO #asdf;

EXEC tempdb..sp_columns #asdf;
COLUMN_NAME TYPE_NAME
IsNullRes Nvarchar
CoalesceRes Int

Με βάση το documentation η ΙSNULL επιστρέφει τον τύπο του πρώτου ορίσματος, ενώ η COALESCE επιστρέφει τον ανώτερο τύπο.

Υ.Γ. Για όποιον θέλει να κάνει δοκιμές το SQL_VARIANT_PROPERTY(@x,'BaseType') είναι ένας εύκολος τρόπος να δει κανείς τον τύπο ενός expression.

Ημερομηνία: 07 October 2017 19:43
Αξιολόγηση:
Κατηγορίες:
Tags:
Share it:

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

ΟΝΟΜΑΤΕΠΩΝΥΜΟ - FULL NAME

EMAIL ADDRESS

Θα φαίνεται το Gravatar εικονίδιο σας

WEB SITE

COMMENT


Πληκτρολογήστε τον αριθμό που βλέπετε :
captcha


 

newsletter subscription

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