go backarticles

Articles of SQLschool.gr Team


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.


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

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

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

Θα μου δώσει:


Και μιας που πιάσαμε το 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;
IsNullRes Nvarchar
CoalesceRes Int

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

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

Fivi Panopoulou

Fivi Panopoulou

Fivi is a Software Engineer specializing in SQL Development. Building data flows and transforming data to enable their meaningful business interpretation is her pursuit. She works with software and reporting systems, from analysis and design to implementation and maintenance.
She has been part of Microsoft technology oriented communities since an undergraduate student. SQL School has inspired her to work with data and become a SQL Server enthusiast from her early steps.


Leave your comment




We use Gravatar




Become a member

If you want to receive updates from us become a member to our community.
Follow us in

Newsletters   About us   Contact us   Terms of Use   Privacy   Register
sql school greece logo
© 2010-2022 All rights reserved

This site uses cookies for operational and analytics purposes only.
By continuing to browse this site, you agree to their use.