sqlschool.gr logo

articles

Articles of SQLschool.gr Team

The GOTO statement in SQL Server

Antonios Chatzipavlis
Friday 27 August 2021

Overview

Το να γράψω το συγκεκριμένο άρθρο ήταν μια προσωπική πρόκληση. Είμαι σίγουρος ότι θα υπάρξουν αντιδράσεις μιας και το GOTO statement έχει εξοβελιστεί στο πυρ το εξώτερον. Όμως δεν έχω καμία διάθεση ή πρόθεση να μπω σε αυτές.

Προσωπικά δεν θεωρώ το GOTO statement κακή πρακτική στο να χρησιμοποιηθεί, αρκεί αυτή να είναι σωστή.

Σαν προγραμματιστής δεν θεωρώ κακό κανένα statement αλλά διαφωνώ στην μη σωστή χρήση του.

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

Σε αυτό το άρθρο θέλω να δείξω το πως μπορεί το GOTO να χρησιμοποιηθεί σωστά στο T-SQL code που γράφουμε ώστε να επιτύχουμε την "καθαρότητα" του κώδικα μας στην εκτέλεση και κυρίως στην ανάγνωση του.

Επίσης να επισημάνω ότι μιλάω μόνο για T-SQL code και σε καμία περίπτωση δεν κάνω αναγωγή σε γλώσσες προγραμματισμού καθώς εκεί έχουμε αρκετές δυνατότητες που δεν υπάρχουν στην SQL language για την αποφυγή της χρήσης του. Τέλος να αναφέρω ότι σε καμία περίπτωση δεν εγκρίνω την χρήση του που οδηγεί σε spaghetti code.

Existing usage in system stored procedures

Αν κοιτάξουμε με το παρακάτω query στα system object θα βρούμε πάνω από 250 stored procedures που περιέχουν GOTO και αν με την sp_helptext δούμε το κώδικα κάποιων από αυτές θα βρούμε αρκετά patterns που δείχνουν την χρήση του.

SQL Script

select object_schema_name(object_id) as [schema_name], object_name(object_id) as [object_name]
from sys.system_sql_modules 
where definition like '%goto%'

Τα περισσότερα από αυτά έχουν να κάνουν με error trapping και transactions. Για να προλάβω αντιδράσεις να πω ότι αρκετές από αυτές είναι γραμμένες πριν την υποστήριξη του begin try/catch στο SQL Server.

Possible use cases

Γενικότερα θα δείτε και άλλα patterns που είναι χρήσιμα όμως θα εστιάσω σε δύο από αυτά καθώς κάνουν την ζωή μας ευκολότερη τόσο στην ανάγνωση όσο και στην συντήρηση του κώδικα που γράφουμε σε stored procedures, trigger κ.λ.π.

Avoid code repeat

Μια χρήση είναι για την αποφυγή επανάληψης του ίδιου κώδικα όπως στο παράδειγμα.

SQL Script

create procedure pname @p1 int
as
begin

    ... -- a lot of code lines 

    if ( @p1 = x )
    begin
        goto samecode;
    end

    if ( @p1 = y )
    begin
        goto samecode;
    end

    goto exitsp

    samecode:
    ... -- code

    exitsp:
    ... -- safe exit
    return
end
go

Για να προλάβω πάλι τις αντιδράσεις που λένε να βάλω αυτό σε κάποιο άλλο function ή stored procedure και να το καλώ όπου χρειάζεται να πω ότι ναι είναι μια λύση αλλά αυξάνει τα dependencies και σε αρκετές περιπτώσεις το performance καθώς μιλάμε για executions plans από διαφορετικά objects που πρέπει να συνεργαστούν.

Ιδανικά θα ήθελα να έχω μια λογική gosub/return αλλά δεν την έχουμε διαθέσιμη στην T-SQL και ναι μεν μπορείς να το κάνεις με flags αλλά δεν μου αρέσει και τόσο γιατί πάμε στη λογική του μακαρονιού.

Multiple IF/ELSE cases

Μία χρήση που την χρησιμοποιώ αρκετά καθώς με βοηθάει στο να έχω καθαρό κώδικα και να μην χάνομαι μέσα σε αυτό είναι όταν έχω cases.

Δυστυχώς στην T-SQL δεν υπάρχει η λογική της switch όπως πχ σε C#. Ναι ξέρω θα μου πείτε για την CASE αλλά η CASE παίζει μόνο συνδυαστικά με κάποιο άλλο statement. Οπότε αναγκαστικά παίζεις με IF… ELSE και εκεί αν έχεις πολλά χάνεται το μάτι και ο έλεγχος ιδιαίτερα όταν στο κάθε IF υπάρχουν αρκετές γραμμές κώδικα, μάλιστα ούτε η χρήση tabs (indention) στο κώδικα δεν σε σώζει.

Δείτε το παρακάτω παράδειγμα και σκεφτείτε να υπάρχει αρκετός κώδικας μέσα σε κάθε IF...ELSE

SQL Script

create procedure pname @p1 int
as
begin

    if ( @p1 = x )
    begin
        ...
    end

    else if ( @p1 = y )
    begin
        ....
    end

    else if ( @p1 = z )
    begin
        ....
    end
    
    else
    begin
        ...
    end

    return
end
go

Θα μπορούσε να γίνει όπως παρακάτω και αυτό βοηθάει αρκετά στην συντήρηση και ανάγνωση του κώδικα.

SQL Script

create procedure pname @p1 int
as
begin

    
    if ( @p1 = x ) goto caseX
    if ( @p1 = y ) goto caseY
    if ( @p1 = z ) goto caseZ
    else goto caseother
    return

    caseX:
        ....
        return

    caseY:
        ....
        return

    caseZ:
        ....
        return

    caseother:
        ....
        return

end
go

Summary

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

Τέλος να πω ότι τα παραδείγματα που παρατέθηκαν στον άρθρο αυτό επιδέχονται αλλαγών αλλά τα κράτησα απλά ώστε να γίνει κατανοητό το νόημα.

Antonios Chatzipavlis

Antonios Chatzipavlis

Antonios Chatzipavlis is a highly experienced Data Solutions Consultant and Trainer. He has been working in the IT industry since 1988, holding various roles such as senior developer, IT Manager, Data & AI Solutions Architect and Consultant.

Since 1995, Antonios has focused on modern technologies and software development tools, primarily by Microsoft. He has specialized in Data & AI since 2000, with expertise in Microsoft Data Platform (SQL Server, Azure SQL Databases, Azure Synapse Analytics, Microsoft Fabric, Power BI, AI) and Databricks.

Antonios is also a Microsoft Certified Trainer (MCT) for over 25 years, has been recognized as a Microsoft Most Valuable Professional (MVP) in Data Platform since 2010 and he is in the Data Expert 40 Powerlist 2024 by Boussias. He is the co-founder and visionary behind XLYTiCA, a company dedicated to Data & AI solutions.

Episode

Task Flows in Microsoft Fabric

image

More Episodes...

Tip

Get Certified: Become a Fabric Data Engineer

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-2025 All rights reserved

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