go backarticles

Articles of SQLschool.gr Team

SOME T-SQL IMPLICIT CASTING TRAPS

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.


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.

  

Relative Articles

Leave your comment

COMMENT

FULL NAME

EMAIL ADDRESS

We use Gravatar

WEB SITE



captcha


 

Newsletter

If you want to receive updates from us subscribe below with your email.
Follow us in
PASS chapter logo

The Official PASS Local Group for Greece

About us Contact us Terms of Use Privacy Sing in Register
sql school greece logo
© 2010-2020 All rights reserved

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