sqlschool.gr logo

articles

Articles of SQLschool.gr Team

The ARITHABORT and ROUND_ABORT settings

Fivi Panopoulou - Sotiris Karras
Wednesday 16 September 2015

Είναι γνωστό ότι στον SQL Server υπάρχουν διάφορα SET options που καθορίζουν την συμπεριφορά του με συγκεκριμένους τρόπους. Σε αυτό  το post, θα μιλήσουμε για τι είδους έλεγχο μας δίνουν τέτοια options σε περίπτωση "προβληματικών" αριθμητικών πράξεων. Πιο συγκεκριμένα, θα δούμε τα ARITHABORT και NUMERIC_ROUNDABORT settings.

To πρώτο εξ αυτών σχετίζεται με δύο περιπτώσεις: την διαίρεση με μηδέν και το overflow. Με βάση αυτό κρίνεται αν θα πάρουμε πίσω αποτέλεσμα (NULL) ή/και κάποιο warning ή error.

Για παράδειγμα, ας δούμε τι θα γίνει όταν τρέξουμε τα παρακάτω:

SET ANSI_WARNINGS ON;
SET ARITHABORT ON;

PRINT 'overflow'
SELECT CAST(256 AS TINYINT) res;

PRINT 'division by zero'
SELECT 2/0 AS res;
GO

Θα πάρουμε τα παρακάτω μηνύματα και κανένα result. To ίδιο αποτέλεσμα θα φέρει και με ANSI_WARNINGS ON και ARITHABORT OFF.

 

Αντίστοιχα ακολουθούν και τα αποτελέσματα του ίδιου batch με ANSI_WARNING OFF, ARITHABORT ON:

 

Τέλος, στην περίπτωση στην οποία και το ANSI_WARNINGS είναι OFF και το ARITHABORT είναι OFF, το παραπάνω batch θα μας επιστρέψει δύο φορές NULL result set.

Το δεύτερο setting, το NUMERIC_ROUNDABORT, έχει να κάνει με το πώς διαχειρίζεται ο SQL Server το precision loss σε αριθμητικές πράξεις. Το SET NUMERIC_ROUNDABORT { ON | OFF } , θέτει το error level του SQL Server όταν πραγματοποιείται μία αριθμητική πράξη, η οποία προκαλεί precision loss από το τελικό αποτέλεσμα. Για παράδειγμα ας δούμε τι επιστρέφουν τα παρακάτω queries:

-- ROUNDABORT OFF;
-- ARITHABORT ON,OFF;
SET NOCOUNT ON;
SET NUMERIC_ROUNDABORT OFF;
DECLARE @var1 DECIMAL(3,1),
     @var2 DECIMAL(3,2),
     @res  DECIMAL(3,1);
SET @var1 = 10.1;
SET @var2 = 0.01;
SET @res = @var1 + @var2;
SELECT @res AS result;
GO

-- ROUNDABORT ON;
-- ARITHABORT OFF;
SET NOCOUNT ON;
SET NUMERIC_ROUNDABORT ON;
SET ARITHABORT OFF;
DECLARE @var1 DECIMAL(3,1),
        @var2 DECIMAL(3,2),
        @res  DECIMAL(3,1);
SET @var1 = 10.1;
SET @var2 = 0.01;
SET @res = @var1 + @var2;
SELECT @res AS result;
GO

 

 Το πρώτο batch μας πληροφορεί για την τιμή του NUMERIC_ROUNDABORT server. Στα επόμενα batches επιχειρούμε μία πρόσθεση η οποία προκαλεί precision loss από το αποτέλεσμα. Όντως, η μεταβλητή @res θα έπρεπε να περιέχει την τιμή 10.11, όμως έχει οριστεί σαν αριθμός με ακρίβεια ένα δεκαδικό ψηφίο. Τι θα συμβεί αν εκτελεστούν τα παραπάνω queries;

Tο αποτέλεσμα το οποίο θα επιστραφεί στην πρώτη περίπτωση θα είναι το 10.1 (στρογγυλοποίηση και precision loss), στην δεύτερη περίπτωση NULL και στην τελευταία το error:  

 

 

Σημείωση1: Ακολουθώντας τους κανονισμούς που ισχύουν για τα SET statements του SQL Server, το NUMERIC_ROUNDABORT πρέπει να είναι OFF για την δημιουργία και αλλαγή indexes πάνω σε indexed views και computed columns.

 

Σημείωση2: Από τον SQL Server 2005 και έπειτα θέτοντας τα SET ANSI_WARNIGS ON, τίθεται αυτόματα και το ARITHABORT ON.

 

Σημείωση3: Το ARITHABORT OFF μπορεί να επηρεάσει αρνητικά το performance, καθώς μπορεί να επηρεάσει αρνητικά τον query optimizer.  Στo SSMS by default  το ARITHABORT είναι ΟΝ. Αυτό θα πρέπει να το έχουμε υπ’ όψιν αν η εφαρμογή μας έχει διαφορετικό setting, καθώς δοκιμάζοντας queries της εφαρμογής στο management studio μπορεί να έχουμε διαφορετικό execution plan και να τρέχουν γρηγορότερα από ότι τα είδαμε να τρέχουν στην εφαρμογή.

Fivi Panopoulou

Fivi Panopoulou

Το 2007 ξεκίνησα τις σπουδές μου στη σχολή Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών στο Εθνικό Μετσόβιο Πολυτεχνείο.Κατά την διάρκεια των σπουδών μου εκεί αγάπησα τον προγραμματισμό και τα συστήματα πληροφορικής, καθώς επίσης απέκτησα το ιδιαίτερο ενδιαφέρον μου για τις βάσεις δεδομένων. Κατά την διάρκεια της διπλωματικής μου ασχολήθηκα με ζητήματα ανωνυμοποίησης δεδομένων και την ανάπτυξη σχετικού εργαλείου. Τα τελευταία χρόνια των σπουδών μου, μου δόθηκε η ευκαιρία να ασχοληθώ περισσότερο και να διευρύνω τους ορίζοντές μου ως Microsoft Student Partner και μέσω της κοινότητας Student Guru. Στα πλαίσια των κοινοτήτων αυτών, ξεκίνησα να ασχολούμαι με παρουσιάσεις αλλά και να γνωρίζω τον SQL Server. Από την πρώτη στιγμή που ασχολήθηκα μαζί του, συνειδητοποίησα πόσο ήθελα να εμβαθύνω τις γνώσεις μου σχετικά με αυτόν και τα συστήματα διαχείρισης βάσεων δεδομένων γενικότερα, πράγμα που προσπαθώ να κάνω έκτοτε. Πριν χρόνια είχα την τύχη να συμμετέχω στο πρόγραμμα mentoring, μέσω του οποίου γνώρισα τον κ. Χατζηπαυλή. Από τότε συμμετέχω στην ομάδα του SQLschool.gr.


Sotiris Karras

Sotiris Karras

Είμαι απόφοιτος της σχολής Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών του Εθνικού Μετσόβιου Πολυτεχνείου και στα ενδιαφέροντά μου συμπεριλαμβάνεται o τομέας του Knowledge and Data Engineering. Πιο συγκεκριμένα, έχω ασχοληθεί ακαδημαϊκά και ερευνητικά με τον τομέα του data privacy και data anonymity, ενώ πάθος μου είναι ό,τι έχει να κάνει με relational databases και data management. Στο παρελθόν, έχω συνεργαστεί με την Microsoft Hellas ως Microsoft Student Partner για ακαδημαϊκές δραστηριότητες και ήμουν μέρος του MVP mentoring προγράμματός της, στο οποίο είχα την τύχη να γνωρίσω τον κ. Χατζηπαυλή.

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.