sqlschool.gr logo

articles

Articles of SQLschool.gr Team

SOME T-SQL IMPLICIT CASTING TRAPS

Fivi Panopoulou
Saturday 07 October 2017

Θα ξεκινήσω με το 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.

Tip

What's New in SQL Server 2022 - Episodes

More Tips...

Become a member

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

Connect

Explore

Learn


sqlschool.gr © 2010-2024 All rights reserved

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