go backarticles

Articles of SQLschool.gr Team

SET vs SELECT when setting variables

Fivi Panopoulou - Sotiris Karras

Στην T-SQL υπάρχουν δύο τρόποι με τους οποίους μπορεί κανείς να θέσει μια μεταβλητή. Ο πρώτος είναι με το SET και ο δεύτερος είναι με την χρήση του select statement. Και οι δύο τρόποι χρησιμοποιούνται ευρέως, σε ποια σημεία όμως διαφέρουν μεταξύ τους; Σε αυτό το post θα δούμε δύο σημαντικά σημεία στα οποία διαφοροποιούνται.

Η πρώτη διαφορά εντοπίζεται όταν θέλουμε να θέσουμε μια μεταβλητή με βάση το αποτέλεσμα ενός query το οποίο μπορεί να μας επιστρέψει περισσότερες από μια γραμμές. Για παράδειγμα στην Northwind το παρακάτω query μας επιστρέφει 8 διαφορετικά id.

SELECT ProductID  
FROM Products
WHERE Discontinued = 1;

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


-- 1) setting the variable with SET
DECLARE @Pid INT;

SET @Pid = (SELECT ProductID  
FROM Products
WHERE Discontinued = 1);

SELECT @Pid;
GO

----------------------------------------
-- 2) setting the variable with SELECT

DECLARE @Pid INT;

SELECT @Pid = ProductID  
FROM Products
WHERE Discontinued = 1;

SELECT @Pid;
GO

Στην πρώτη περίπτωση ο SQL Server θα καταλάβει ότι έπρεπε το query να επιστρέφει μόνο ένα αποτέλεσμα και ότι υπάρχει λάθος, επιστρέφοντάς μας το κατάλληλο error:

"Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression."

Στην δεύτερη περίπτωση το query θα τρέξει χωρίς κανένα μήνυμα σφάλματος και η μεταβλητή @Pid θα λάβει την τελευταία τιμή του result set. Στην περίπτωσή μας επέστρεψε 53, αλλά θα πρέπει να τονιστεί ότι δεν υπάρχει καμία εγγύηση για το ποια θα είναι η τελευταία τιμή και άρα ποιο θα είναι τελικά η τιμή της μεταβλητής.

Η δεύτερη διαφορά εντοπίζεται όταν το query δεν επιστρέφει αποτελέσματα. Για παράδειγμα στην northwind το παρακάτω query μας επιστρέφει κενό result set.

SELECT ProductID  
FROM Products
WHERE CategoryID = 9;

Ας πάμε λοιπόν να θέσουμε μια μεταβλητή @Pid με καθέναν από τους δύο τρόπους που αναφέρθηκαν, όπως φαίνεται παρακάτω.

-- 1) setting the variable with SET
DECLARE @Pid INT = 0;

SET @PID = (SELECT ProductID  
FROM Products
WHERE CategoryID = 9);

SELECT @Pid;
GO
----------------------------------------
-- 2) setting the variable with SELECT


DECLARE @Pid INT = 0;

SELECT @Pid = ProductID  
FROM Products
WHERE  CategoryID = 9;

SELECT @Pid;
GO

Στην πρώτη περίπτωση το αποτέλεσμα θα είναι NULL, δείχνοντάς μας ότι δεν υπήρχε το id που θέλαμε. Στην δεύτερη περίπτωση δεν θα γίνει καμία ανάθεση και το @Pid θα συνεχίσει να έχει την τιμή που έχει πριν, δηλαδή 0.


Fivi Panopoulou

Fivi Panopoulou

System Engineer • Speaker

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


Sotiris Karras

Sotiris Karras

System Engineer • Speaker

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


Relative Articles

Comments

user-gravatar

On 22 Sep 2016 @ 10:59 AM Sotiris Filippidis wrote:

Ποτέ δεν είχε πάει το μυαλό μου! Χρησιμοποιούσα SET όταν ανέθετα στατικές τιμές και SELECT όταν ανέθετα τιμές από queries. Αν και στο πρώτο παράδειγμα η διαφορά μεταξύ set/select εύκολα εξομαλύνεται με τη χρήση του TOP 1 για να είμαστε σίγουροι ότι δεν έχουμε πολλαπλά αποτελέσματα, στο δεύτερο παράδειγμα τα πράγματα είναι πιό ενδιαφέροντα (γιατί μην μου πει κανείς ότι φροντίζει και για default value στο query σε τέτοια περίπτωση) και λανθασμένη χρήση μπορεί να οδηγήσει σε bugs, άρα καλό είναι να το έχουμε υπόψη.

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.