Δρομείς σε αποθηκευμένες διαδικασίες MySQL. Δρομείς στο Mysql Τροποποίηση και διαγραφή σειρών μέσω δρομέων

Ένας ρητός δρομέας είναι μια εντολή SELECT που ορίζεται ρητά στην ενότητα δήλωσης ενός προγράμματος. Όταν δηλώνετε έναν ρητό δρομέα, του δίνεται ένα όνομα. Δεν μπορούν να οριστούν ρητά δρομείς για εντολές INSERT, UPDATE, MERGE και DELETE.

Ορίζοντας την εντολή SELECT ως ρητό δρομέα, ο προγραμματιστής έχει τον έλεγχο των βασικών σταδίων ανάκτησης πληροφοριών από τη βάση δεδομένων Oracle. Καθορίζει πότε να ανοίξετε τον κέρσορα (OPEN), πότε να επιλέξετε σειρές από αυτόν (FETCH), πόσες σειρές να επιλέξετε και πότε να κλείσετε τον δρομέα χρησιμοποιώντας την εντολή CLOSE. Πληροφορίες σχετικά με την τρέχουσα κατάσταση του δρομέα είναι διαθέσιμες μέσω των χαρακτηριστικών του. Αυτή η υψηλή ευαισθησία ελέγχου είναι που κάνει τους ρητούς δρομείς ένα ανεκτίμητο εργαλείο για τον προγραμματιστή.

Ας δούμε ένα παράδειγμα:

1 ΣΥΝΑΡΤΗΣΗ jealousy_level (2 NAME_IN ΣΕ φίλους.NAME%TYPE) ΕΠΙΣΤΡΟΦΗ ΑΡΙΘΜΟΥ 3 ΩΣ 4 CURSOR jealousy_cur 5 IS 6 ΕΠΙΛΟΓΗ τοποθεσίας ΑΠΟ φίλους 7 WHERE NAME = UPPER (NAME_IN); 8 8 jealousy_rec jealousy_cur%ROWTYPE; 9 επανάληψη ΑΡΙΘΜΟΣ; 10 ΑΡΧΗ 11 ΑΝΟΙΞΤΕ jealousy_cur; 13 12 FETCH jealousy_cur INTO jealousy_rec; 15 13 ΑΝ jealousy_cur%FOUND 14 ΤΟΤΕ 15 ΑΝ jealousy_rec.location = "ΠΟΥΕΡΤΟ ΡΙΚΟ" 16 ΤΟΤΕ retval:= 10; 17 ELSIF jealousy_rec.location = "CHICAGO" 18 ΜΕΤΑ retval:= 1; 19 ΤΕΛΟΣ ΑΝ; 20 ΤΕΛΟΣ ΑΝ; 24 21 ΚΛΕΙΣΙΜΟ jealousy_cur; 26 22 RETURN retval; 23 ΕΞΑΙΡΕΣΗ 24 ΟΤΑΝ ΑΛΛΟΙ ΤΟΤΕ 25 ΑΝ jealousy_cur%ISOPEN ΤΟΤΕ 26 ΚΛΕΙΣΙΜΟ jealousy_cur; 27 ΤΕΛΟΣ ΑΝ; 28 ΤΕΛΟΣ;

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

Δήλωση ρητής δρομέα

Για να μπορείτε να χρησιμοποιήσετε έναν ρητό δρομέα, πρέπει να δηλωθεί στην ενότητα δήλωσης του μπλοκ ή του πακέτου PL/SQL:

CURSOR cursor_name [ ([ παράμετρος [, παράμετρος...]) ] [ RETURN specification_reEirn ] IS SELECT_command ];

Εδώ το όνομα του δρομέα είναι το όνομα του δηλωμένου δρομέα. spiifiction_te?it - προαιρετική ενότητα RETURN. KOMaHdaSELECT - οποιαδήποτε έγκυρη εντολή SQL SELECT. Οι παράμετροι μπορούν επίσης να μεταβιβαστούν στον κέρσορα (δείτε την ενότητα «Παράμετροι δρομέα» παρακάτω). Τέλος, μετά την εντολή ΕΠΙΛΟΓΗ...ΓΙΑ ΕΝΗΜΕΡΩΣΗ, μπορείτε να καθορίσετε μια λίστα στηλών προς ενημέρωση (δείτε επίσης παρακάτω). Μετά τη δήλωση, ο κέρσορας ανοίγει με την εντολή OPEN και οι σειρές ανακτώνται από αυτόν με την εντολή FETCH.

Μερικά παραδείγματα ρητών δηλώσεων δρομέα.

  • Δρομέας χωρίς παραμέτρους. Το σύνολο σειρών που προκύπτει από αυτόν τον κέρσορα είναι το σύνολο των εταιρικών αναγνωριστικών που επιλέγονται από όλες τις σειρές του πίνακα:
CURSOR company_cur ΕΙΝΑΙ SELECT company_id ΑΠΟ εταιρεία.
  • Δρομέας με παραμέτρους.Το σύνολο γραμμών αυτού του δρομέα που προκύπτει περιέχει μια ενιαία γραμμή με το όνομα της εταιρείας που αντιστοιχεί στην τιμή της παραμέτρου που πέρασε:
CURSOR name_cur (company_id_in IN NUMBER) ΕΙΝΑΙ ΕΠΙΛΕΓΜΕΝΟ όνομα ΑΠΟ την εταιρεία ΟΠΟΥ company_id = company_id_in;
  • Δρομέας με ρήτρα RETURN. Το σύνολο γραμμών αυτού του δρομέα που προκύπτει περιέχει όλα τα δεδομένα στον πίνακα υπαλλήλων για το τμήμα ID 10:
CURSOR emp_cur RETURN υπάλληλοι%ROWTYPE IS SELECT * ΑΠΟ εργαζομένους WHERE Department_id = 10;

Όνομα δρομέα

Ένα ρητό όνομα δρομέα πρέπει να έχει μήκος έως 30 χαρακτήρες και να ακολουθεί τους ίδιους κανόνες με άλλα αναγνωριστικά PL/SQL. Το όνομα του δρομέα δεν είναι μεταβλητή - είναι το αναγνωριστικό του δείκτη στο αίτημα. Στο όνομα του δρομέα δεν εκχωρείται τιμή και δεν μπορεί να χρησιμοποιηθεί σε εκφράσεις. Ο κέρσορας χρησιμοποιείται μόνο στις εντολές OPEN, CLOSE και FETCH και για να χαρακτηριστεί το χαρακτηριστικό του δρομέα.

Δήλωση δρομέα σε πακέτο

Οι σαφείς δρομείς δηλώνονται στην ενότητα δήλωσης ενός μπλοκ PL/SQL. Ένας δρομέας μπορεί να δηλωθεί σε επίπεδο πακέτου, αλλά όχι σε μια συγκεκριμένη διαδικασία ή λειτουργία πακέτου. Ένα παράδειγμα δήλωσης δύο δρομέων σε ένα πακέτο:

ΠΑΚΕΤΟ book_info ΕΙΝΑΙ CURSOR titles_cur ΕΙΝΑΙ ΕΠΙΛΟΓΟΣ τίτλος ΑΠΟ βιβλία. CURSOR books_cur (title_filter_in IN books.title%TYPE) RETURN books%ROWTYPE IS SELECT * FROM books WHERE title LIKE title_filter_in; ΤΕΛΟΣ;

Ο πρώτος δρομέας titles_cur επιστρέφει μόνο τίτλους βιβλίων. Το δεύτερο, books_cur , επιστρέφει όλες τις σειρές του πίνακα βιβλίων στις οποίες τα ονόματα των βιβλίων ταιριάζουν με το μοτίβο που έχει καθοριστεί ως παράμετρος δρομέα (για παράδειγμα, "Όλα τα βιβλία που περιέχουν τη συμβολοσειρά "PL/SQL"). Σημειώστε ότι ο δεύτερος κέρσορας χρησιμοποιεί μια ενότητα RETURN, η οποία δηλώνει τη δομή δεδομένων που επιστρέφεται από την εντολή FETCH.

Η ενότητα RETURN μπορεί να περιέχει οποιαδήποτε από τις ακόλουθες δομές δεδομένων:

  • Μια εγγραφή που ορίζεται από μια γραμμή πίνακα δεδομένων χρησιμοποιώντας το χαρακτηριστικό %ROWTYPE.
  • Μια καταχώρηση που ορίζεται από έναν άλλο δρομέα που είχε δηλώσει προηγουμένως, χρησιμοποιώντας επίσης το χαρακτηριστικό %rowtype.
  • Μια καταχώρηση που ορίζεται από τον προγραμματιστή.

Ο αριθμός των παραστάσεων στη λίστα επιλογής δρομέα πρέπει να ταιριάζει με τον αριθμό των στηλών στην εγγραφή του table_name%ROWTYPE, του Kypcop%ROWTYPE ή του τύπου εγγραφής. Οι τύποι δεδομένων των στοιχείων πρέπει επίσης να είναι συμβατοί. Για παράδειγμα, εάν το δεύτερο στοιχείο της λίστας επιλογής είναι τύπου NUMBER, τότε η δεύτερη στήλη της καταχώρισης στην ενότητα RETURN δεν μπορεί να είναι τύπου VARCHAR2 ή BOOLEAN.

Πριν προχωρήσουμε σε μια λεπτομερή εξέταση της ενότητας RETURN και των πλεονεκτημάτων της, ας καταλάβουμε πρώτα γιατί μπορεί να είναι απαραίτητο να δηλώσουμε δρομείς σε ένα πακέτο; Γιατί να μην δηλώσετε έναν ρητό δρομέα στο πρόγραμμα στο οποίο χρησιμοποιείται - σε μια διαδικασία, συνάρτηση ή ανώνυμο μπλοκ;

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

Αξίζει επίσης να σκεφτείτε τη δημιουργία μιας συνάρτησης που επιστρέφει μια μεταβλητή δρομέα με βάση το REF CURSOR . Το πρόγραμμα που καλεί ανακτά σειρές μέσω μιας μεταβλητής δρομέα. Για περισσότερες πληροφορίες, ανατρέξτε στην ενότητα "Μεταβλητές δρομέα και ΔΕΡΜΕΑΣ ΑΝΑΦΟΡΑΣ".

Όταν δηλώνετε δρομείς σε επαναχρησιμοποιήσιμα πακέτα, πρέπει να λάβετε υπόψη ένα σημαντικό πράγμα. Όλες οι δομές δεδομένων, συμπεριλαμβανομένων των δρομέων, που δηλώνονται σε «επίπεδο πακέτου» (όχι μέσα σε μια συγκεκριμένη συνάρτηση ή διαδικασία), διατηρούν τις τιμές τους σε όλη τη διάρκεια της συνεδρίας. Αυτό σημαίνει ότι ο δρομέας παρτίδας θα παραμείνει ανοιχτός μέχρι να τον κλείσετε ρητά ή μέχρι να τελειώσει η περίοδος λειτουργίας. Οι δρομείς που δηλώνονται σε τοπικά μπλοκ κλείνουν αυτόματα όταν ολοκληρωθούν αυτά τα μπλοκ.

Τώρα ας δούμε την ενότητα ΕΠΙΣΤΡΟΦΗ. Ένα ενδιαφέρον πράγμα σχετικά με τη δήλωση ενός δρομέα σε ένα πακέτο είναι ότι η κεφαλίδα του δρομέα μπορεί να διαχωριστεί από το σώμα του. Αυτή η κεφαλίδα, που θυμίζει περισσότερο μια κεφαλίδα συνάρτησης, περιέχει πληροφορίες που χρειάζεται ο προγραμματιστής για να εργαστεί: το όνομα του δρομέα, τις παραμέτρους του και τον τύπο των δεδομένων που επιστρέφονται. Το σώμα του δρομέα είναι η εντολή SELECT. Αυτή η τεχνική παρουσιάζεται στη νέα έκδοση της δήλωσης δρομέα books_cur στο πακέτο book_info:

PACKAGE book_info ΕΙΝΑΙ CURSOR books_cur (title_filter_in IN books.title%TYPE) RETURN books%ROWTYPE; ΤΕΛΟΣ; PACKAGE BODY book_info IS CURSOR books_cur (title_filter_in IN books.title%TYPE) ΕΠΙΣΤΡΟΦΗ βιβλίων%ROWTYPE IS SELECT * FROM books WHERE title LIKE title_filter_in; ΤΕΛΟΣ;

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

  • Απόκρυψη πληροφοριών. Ο κέρσορας στη συσκευασία είναι ένα "μαύρο κουτί". Αυτό είναι βολικό για τους προγραμματιστές επειδή δεν χρειάζεται να γράψουν ή καν να δουν την εντολή SELECT. Αρκεί να γνωρίζουμε ποιες εγγραφές επιστρέφει αυτός ο κέρσορας, με ποια σειρά και ποιες στήλες περιέχουν. Ένας προγραμματιστής που εργάζεται με το πακέτο χρησιμοποιεί τον κέρσορα όπως κάθε άλλο έτοιμο στοιχείο.
  • Ελάχιστη ανασύνταξη. Με την απόκρυψη του ορισμού του ερωτήματος στο σώμα του πακέτου, μπορούν να γίνουν αλλαγές στην εντολή SELECT χωρίς αλλαγή της κεφαλίδας του δρομέα στις προδιαγραφές του πακέτου. Αυτό επιτρέπει τη βελτίωση, τη διόρθωση και την εκ νέου μεταγλώττιση του κώδικα χωρίς την εκ νέου μεταγλώττιση των προδιαγραφών του πακέτου, έτσι ώστε τα προγράμματα που εξαρτώνται από αυτό το πακέτο να μην επισημαίνονται ως μη έγκυρα και να μην χρειάζεται να μεταγλωττιστούν εκ νέου.

Άνοιγμα ρητού δρομέα

Η χρήση ενός δρομέα ξεκινά με τον ορισμό του στην ενότητα δηλώσεων. Στη συνέχεια, ο δηλωμένος δρομέας πρέπει να ανοίξει. Η σύνταξη για την πρόταση OPEN είναι πολύ απλή:

OPEN cursor_name [ (όρισμα [, όρισμα...]) ];

Εδώ, το όνομα του δρομέα είναι το όνομα του δρομέα που δηλώθηκε προηγουμένως και το όρισμα είναι η τιμή που μεταβιβάζεται στον δρομέα εάν δηλώνεται με μια λίστα παραμέτρων.

Η Oracle υποστηρίζει επίσης τη σύνταξη FOR κατά το άνοιγμα ενός δρομέα, η οποία χρησιμοποιείται και για τις μεταβλητές του δρομέα (δείτε την ενότητα "Μεταβλητές δρομέα και REF CURSOR") όσο και για την ενσωματωμένη δυναμική SQL.

Όταν το PL/SQL ανοίγει έναν δρομέα, εκτελεί το ερώτημα που περιέχει. Επιπλέον, προσδιορίζει το ενεργό σύνολο δεδομένων - τις σειρές όλων των πινάκων που συμμετέχουν στο ερώτημα που ταιριάζουν με το κριτήριο WHERE και τη συνθήκη σύνδεσης. Η εντολή OPEN δεν ανακτά δεδομένα - αυτή είναι η δουλειά της εντολής FETCH.

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

Επιπλέον, εάν η εντολή SELECT περιέχει μια ενότητα ΓΙΑ ΕΝΗΜΕΡΩΣΗ, όλες οι σειρές που προσδιορίζονται από τον κέρσορα κλειδώνονται όταν ανοίγει ο δρομέας.

Εάν προσπαθήσετε να ανοίξετε έναν δρομέα που είναι ήδη ανοιχτός, το PL/SQL θα εμφανίσει το ακόλουθο μήνυμα λάθους:

ORA-06511: PL/SQL: ο κέρσορας είναι ήδη ανοιχτός

Επομένως, πριν ανοίξετε τον κέρσορα, θα πρέπει να ελέγξετε την κατάστασή του χρησιμοποιώντας την τιμή του χαρακτηριστικού %είναι ανοιχτό:

ΑΝ ΟΧΙ company_cur%ISOPEN ΤΟΤΕ ΑΝΟΙΞΤΕ company_cur; ΤΕΛΟΣ ΕΑΝ;

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

Εάν ένα πρόγραμμα εκτελεί έναν βρόχο FOR χρησιμοποιώντας έναν δρομέα, ο δρομέας δεν χρειάζεται να ανοίξει ρητά (ανάκτηση, κλείσιμο). Ο κινητήρας PL/SQL το κάνει αυτό αυτόματα.

Ανάκτηση δεδομένων από έναν ρητό δρομέα

Η εντολή SELECT δημιουργεί έναν εικονικό πίνακα - ένα σύνολο γραμμών που ορίζονται από μια πρόταση WHERE με στήλες που ορίζονται από μια λίστα στηλών SELECT. Έτσι, ο κέρσορας αντιπροσωπεύει αυτόν τον πίνακα στο πρόγραμμα PL/SQL. Ο πρωταρχικός σκοπός ενός δρομέα σε προγράμματα PL/SQL είναι να επιλέγει σειρές για επεξεργασία. Η ανάκτηση των σειρών του δρομέα γίνεται με την εντολή FETCH:

FETCH cursor_name INTO record_or_variable_list?

Εδώ, το όνομα του δρομέα είναι το όνομα του δρομέα από τον οποίο επιλέγεται η εγγραφή και η εγγραφή ή η λίστα μεταβλητών είναι οι δομές δεδομένων PL/SQL στις οποίες αντιγράφεται η επόμενη σειρά του ενεργού συνόλου εγγραφών. Τα δεδομένα μπορούν να τοποθετηθούν σε μια εγγραφή PL/SQL (δηλωμένη με το χαρακτηριστικό %ROWTYPE ή δήλωση TYPE) ή σε μεταβλητές (μεταβλητές PL/SQL ή μεταβλητές σύνδεσης - όπως στα στοιχεία Oracle Forms).

Παραδείγματα ξεκάθαρων δρομέων

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

  • Ανάκτηση δεδομένων από έναν δρομέα σε μια εγγραφή PL/SQL:
ΔΗΛΩΣΗ ΔΙΑΔΡΟΜΕΑ Η εταιρεία_cur είναι ΕΠΙΛΟΓΗ ...; company_rec company_cur%ROWTYPE; ΑΡΧΙΣΤΕ ΑΝΟΙΓΜΑ company_cur; FETCH company_cur INTO company_rec;
  • Ανάκτηση δεδομένων από έναν δρομέα σε μια μεταβλητή:
ΑΝΑΛΗΨΗ new_balance_cur ΣΕ new_balance_dollars.
  • Ανάκτηση δεδομένων από έναν δρομέα σε μια γραμμή πίνακα PL/SQL, μια μεταβλητή και μια μεταβλητή δέσμευσης Oracle Forms:
FETCH emp_name_cur INTO emp_name (1), hiredate, :dept.min_salary;

Τα δεδομένα που λαμβάνονται από έναν δρομέα πρέπει πάντα να τοποθετούνται σε μια εγγραφή που δηλώνεται κάτω από τον ίδιο δρομέα με το χαρακτηριστικό %ROWTYPE. Αποφύγετε την επιλογή λιστών μεταβλητών. Η ανάκτηση σε μια εγγραφή κάνει τον κώδικα πιο συμπαγή και ευέλικτο, επιτρέποντάς σας να αλλάξετε τη λίστα ανάκτησης χωρίς να αλλάξετε την εντολή FETCH.

Δειγματοληψία μετά την επεξεργασία της τελευταίας σειράς

Μόλις ανοίξετε τον κέρσορα, επιλέγετε γραμμές από αυτόν μία προς μία μέχρι να εξαντληθούν όλες. Ωστόσο, μπορείτε ακόμα να εκδώσετε την εντολή FETCH μετά από αυτό.

Παραδόξως, το PL/SQL δεν κάνει εξαίρεση σε αυτήν την περίπτωση. Απλώς δεν κάνει τίποτα. Δεδομένου ότι δεν υπάρχει τίποτα άλλο για επιλογή, οι τιμές των μεταβλητών στην ενότητα INTO της εντολής FETCH δεν αλλάζουν. Με άλλα λόγια, η εντολή FETCH δεν ορίζει αυτές τις μεταβλητές σε NULL.

Ρητά ψευδώνυμα στηλών δρομέα

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

Ένα ψευδώνυμο στήλης είναι ένα εναλλακτικό όνομα που καθορίζεται στην εντολή SELECT για μια στήλη ή μια παράσταση. Ορίζοντας κατάλληλα ψευδώνυμα στο SQL*Plus, μπορείτε να εμφανίσετε τα αποτελέσματα ενός αυθαίρετου ερωτήματος σε αναγνώσιμη από τον άνθρωπο μορφή. Σε αυτές τις περιπτώσεις, τα ψευδώνυμα δεν είναι απαραίτητα. Από την άλλη πλευρά, όταν χρησιμοποιείτε ρητούς δρομείς, απαιτούνται υπολογισμένα ψευδώνυμα στηλών στις ακόλουθες περιπτώσεις:

  • κατά την ανάκτηση δεδομένων από έναν δρομέα σε μια εγγραφή που δηλώνεται με το χαρακτηριστικό %ROWTYPE που βασίζεται στον ίδιο δρομέα.
  • όταν ένα πρόγραμμα περιέχει αναφορά σε μια υπολογιζόμενη στήλη.

Εξετάστε το ακόλουθο ερώτημα. Η εντολή SELECT επιλέγει τα ονόματα όλων των εταιρειών που παρήγγειλαν αγαθά κατά τη διάρκεια του 2001, καθώς και το συνολικό ποσό των παραγγελιών (υποθέτοντας ότι η προεπιλεγμένη μάσκα μορφοποίησης για την τρέχουσα παρουσία βάσης δεδομένων είναι ΗΗ-ΔΕΥ-ΕΕΕΕ):

SELECT company_name, SUM (inv_amt) FROM company c, invoice i WHERE c.company_id = i.company_id ΚΑΙ i.invoice_date ΜΕΤΑΞΥ "01-JAN-2001" ΚΑΙ "31-DEC-2001";

Η εκτέλεση αυτής της εντολής στο SQL*Plus θα παράγει την ακόλουθη έξοδο:

ΟΝΟΜΑ ΕΤΑΙΡΕΙΑΣ SUM (INV_AMT)
ACME TURBO INC. 1000
WASHINGTON HAIR CO. 25.20

Όπως μπορείτε να δείτε, η κεφαλίδα στήλης SUM (INV_AMT) δεν είναι κατάλληλη για μια αναφορά, αλλά είναι κατάλληλη για απλή προβολή των δεδομένων. Τώρα ας εκτελέσουμε το ίδιο ερώτημα σε ένα πρόγραμμα PL/SQL χρησιμοποιώντας έναν ρητό δρομέα και ας προσθέσουμε ένα ψευδώνυμο στήλης:

ΔΗΛΩΣΤΕ CURSOR comp_cur ΕΙΝΑΙ ΕΠΙΛΕΓΜΕΝΟ c.name, SUM (inv_amt) total_sales FROM company C, invoice I WHERE C.company_id = I.company_id ΚΑΙ I.invoice_date ΜΕΤΑΞΥ "01-JAN-2001" ΚΑΙ "31-DEC-2"; comp_rec comp_cur%ROWTYPE; ΑΡΧΙΣΤΕ ΑΝΟΙΓΜΑ comp_cur; FETCH comp_cur INTO comp_rec; ΤΕΛΟΣ;

Χωρίς το ψευδώνυμο, δεν θα μπορώ να αναφέρω τη στήλη στη δομή εγγραφής comp_rec. Εάν έχετε ψευδώνυμο, μπορείτε να εργαστείτε με μια υπολογισμένη στήλη όπως θα κάνατε με οποιαδήποτε άλλη στήλη ερωτήματος:

IF comp_rec.total_sales > 5000 THEN DBMS_OUTPUT.PUT_LINE (" Έχετε υπερβεί το πιστωτικό όριο των $5000 κατά " || TO_CHAR (comp_rec.total_sales - 5000, "$9999")); ΤΕΛΟΣ ΕΑΝ;

Όταν επιλέγετε μια σειρά σε μια εγγραφή που δηλώνεται με το χαρακτηριστικό %ROWTYPE, η υπολογισμένη στήλη είναι προσβάσιμη μόνο με το όνομα - επειδή η δομή της εγγραφής καθορίζεται από τη δομή του ίδιου του δρομέα.

Κλείσιμο ρητού δρομέα

Μια φορά κι έναν καιρό στην παιδική ηλικία μας έμαθαν να καθαρίζουμε τον εαυτό μας και αυτή η συνήθεια παρέμεινε μαζί μας (αν και όχι σε όλους) για το υπόλοιπο της ζωής μας. Αποδεικνύεται ότι αυτός ο κανόνας παίζει εξαιρετικά σημαντικό ρόλο στον προγραμματισμό, και ειδικά όταν πρόκειται για τη διαχείριση δρομέων. Μην ξεχνάτε ποτέ να κλείνετε τον κέρσορα όταν δεν τον χρειάζεστε πλέον!

CLOSE σύνταξη εντολής:

ΚΛΕΙΣΙΜΟ όνομα_δρομέα.

Ακολουθούν ορισμένες σημαντικές συμβουλές και σκέψεις που σχετίζονται με το κλείσιμο των ασαφών δρομέων.

  • Εάν ένας δρομέας έχει δηλωθεί και ανοίξει σε μια διαδικασία, φροντίστε να τον κλείσετε όταν τελειώσετε με αυτόν. Διαφορετικά, ο κωδικός σας θα διαρρεύσει στη μνήμη. Θεωρητικά, ένας δρομέας (όπως κάθε δομή δεδομένων) θα πρέπει να κλείνει αυτόματα και να καταστρέφεται όταν βγει εκτός πεδίου εφαρμογής. Συνήθως, κατά την έξοδο από μια διαδικασία, μια συνάρτηση ή ένα ανώνυμο μπλοκ, το PL/SQL κλείνει στην πραγματικότητα όλους τους ανοιχτούς δρομείς μέσα σε αυτό. Αλλά αυτή η διαδικασία απαιτεί πόρους, επομένως για λόγους αποτελεσματικότητας, η PL/SQL καθυστερεί μερικές φορές τον εντοπισμό και το κλείσιμο των ανοιχτών δρομέων. Οι δρομείς τύπου REF CURSOR, εξ ορισμού, δεν μπορούν να κλείσουν σιωπηρά. Το μόνο πράγμα για το οποίο μπορείτε να είστε σίγουροι είναι ότι όταν ολοκληρωθεί το "απώτατο" μπλοκ PL/SQL και ο έλεγχος επιστραφεί στην SQL ή σε άλλο πρόγραμμα κλήσης, το PL/SQL θα κλείσει έμμεσα όλους τους δρομείς που ανοίγουν από αυτό το μπλοκ ή τα ένθετα μπλοκ. εκτός από το REF CURSOR . Το άρθρο "Επαναχρησιμοποίηση δρομέα σε PL/SQL static SQL" από το Oracle Technology Network παρέχει μια λεπτομερή ανάλυση του τρόπου και του πότε το PL/SQL κλείνει τους δρομείς. Τα ένθετα ανώνυμα μπλοκ είναι ένα παράδειγμα μιας κατάστασης στην οποία η PL/SQL δεν κλείνει σιωπηρά τους δρομείς. Για μερικές ενδιαφέρουσες πληροφορίες σχετικά με αυτό το θέμα, ανατρέξτε στο άρθρο του Jonathan Gennick "Does PL/SQL Close Implicitly Cursors?"
  • Εάν ένας δρομέας έχει δηλωθεί σε ένα πακέτο σε επίπεδο πακέτου και είναι ανοιχτός σε κάποιο μπλοκ ή πρόγραμμα, θα παραμείνει ανοιχτός μέχρι να τον κλείσετε ρητά ή μέχρι να τελειώσει η περίοδος λειτουργίας. Επομένως, αφού ολοκληρώσετε την εργασία με έναν δρομέα επιπέδου παρτίδας, θα πρέπει να τον κλείσετε αμέσως με την εντολή ΚΛΕΙΣΙΜΟ (και παρεμπιπτόντως, το ίδιο θα πρέπει να κάνετε στην ενότητα εξαιρέσεων):
ΑΡΧΙΣΤΕ ΑΝΟΙΓΜΑ my_package.my_cursor; ... Εργασία με τον κέρσορα CLOSE my_package.my_cursor; ΕΞΑΙΡΕΣΗ ΟΤΑΝ ΑΛΛΟΙ ΤΟΤΕ ΑΝ mypackage.my_cursor%ISOPEN ΤΟΤΕ ΚΛΕΙΣΤΕ my_package.my_cursor; ΤΕΛΟΣ ΕΑΝ; ΤΕΛΟΣ;
  • Ο κέρσορας μπορεί να κλείσει μόνο εάν ήταν προηγουμένως ανοιχτός. Διαφορετικά, θα δημιουργηθεί μια εξαίρεση INVALID_CURS0R. Η κατάσταση του δρομέα ελέγχεται χρησιμοποιώντας το χαρακτηριστικό %ISOPEN:
ΑΝ company_cur%ISOPEN ΤΟΤΕ ΚΛΕΙΣΤΕ company_cur; ΤΕΛΟΣ ΕΑΝ;
  • Εάν απομένουν πάρα πολλοί ανοιχτοί δρομείς στο πρόγραμμα, ο αριθμός των δρομέων μπορεί να υπερβαίνει την τιμή της παραμέτρου βάσης δεδομένων OPEN_CURSORS. Εάν λάβετε ένα μήνυμα σφάλματος, πρώτα βεβαιωθείτε ότι οι δρομείς που δηλώνονται στα πακέτα είναι κλειστοί όταν δεν χρειάζονται πλέον.

Σαφείς ιδιότητες δρομέα

Η Oracle υποστηρίζει τέσσερα χαρακτηριστικά (%FOUND, %NOTFOUND, %ISOPEN, %ROWCOUNTM) για τη λήψη πληροφοριών σχετικά με την κατάσταση ενός ρητού δρομέα. Μια αναφορά χαρακτηριστικού έχει την ακόλουθη σύνταξη: cursor%attribute

Εδώ δρομέας είναι το όνομα του δηλωμένου δρομέα.

Οι τιμές που επιστρέφονται από σαφείς ιδιότητες δρομέα εμφανίζονται στον Πίνακα. 1.

Τραπέζι 1.Σαφείς ιδιότητες δρομέα

Οι τιμές των χαρακτηριστικών του δρομέα πριν και μετά την εκτέλεση διαφόρων λειτουργιών με αυτά εμφανίζονται στον Πίνακα. 2.

Όταν εργάζεστε με ρητά χαρακτηριστικά δρομέα, λάβετε υπόψη τα ακόλουθα:

  • Εάν επιχειρήσετε να αποκτήσετε πρόσβαση στο χαρακτηριστικό %FOUND, %NOTFOUND ή %ROWCOUNT πριν ανοίξει ο δρομέας ή αφού κλείσει, η Oracle δημιουργεί μια εξαίρεση ΜΗ ΕΓΚΥΡΟΥ ΔΕΡΜΟΤΗ (ORA-01001).
  • Εάν την πρώτη φορά που εκτελείται η εντολή FETCH, το σύνολο γραμμών που προκύπτει είναι κενό, τα χαρακτηριστικά του δρομέα επιστρέφουν τις ακόλουθες τιμές: %FOUND = FALSE , %NOTFOUND = TRUE και %ROWCOUNT = 0 .
  • Όταν χρησιμοποιείτε Μαζική ΣΥΛΛΟΓΗ, το χαρακτηριστικό %ROWCOUNT επιστρέφει τον αριθμό των σειρών που ανακτήθηκαν στις δεδομένες συλλογές.

Πίνακας 2.Τιμές χαρακτηριστικών δρομέα

Λειτουργία %ΒΡΕΘΗΚΑΝ %ΔΕΝ ΒΡΕΘΗΚΕ %ΕΙΝΑΙ ΑΝΟΙΧΤΟ %ROWCOUNT
Πριν ΑΝΟΙΞΕΙ Εξαίρεση
ORA-01001
Εξαίρεση
ORA-01001
ΨΕΥΔΗΣ Εξαίρεση
ORA-01001
Μετά το OPEN ΜΗΔΕΝΙΚΟ ΜΗΔΕΝΙΚΟ ΑΛΗΘΗΣ 0
Πριν από το πρώτο δείγμα FETCH ΜΗΔΕΝΙΚΟ ΜΗΔΕΝΙΚΟ ΑΛΗΘΗΣ 0
Μετά το πρώτο δείγμα
ΦΕΡΩ
ΑΛΗΘΗΣ ΨΕΥΔΗΣ ΑΛΗΘΗΣ 1
Πριν από το επόμενο
ΦΕΡΩ
ΑΛΗΘΗΣ ΨΕΥΔΗΣ ΑΛΗΘΗΣ 1
Μετά την επακόλουθη ΑΝΑΛΗΨΗ ΑΛΗΘΗΣ ΨΕΥΔΗΣ ΑΛΗΘΗΣ Εξαρτάται από τα δεδομένα
Πριν από το τελευταίο δείγμα FETCH ΑΛΗΘΗΣ ΨΕΥΔΗΣ ΑΛΗΘΗΣ Εξαρτάται από τα δεδομένα
Μετά το τελευταίο δείγμα FETCH ΑΛΗΘΗΣ ΨΕΥΔΗΣ ΑΛΗΘΗΣ Εξαρτάται από τα δεδομένα
Πριν από το ΚΛΕΙΣΙΜΟ ΨΕΥΔΗΣ ΑΛΗΘΗΣ ΑΛΗΘΗΣ Εξαρτάται από τα δεδομένα
Μετά το ΚΛΕΙΣΙΜΟ Εξαίρεση Εξαίρεση ΨΕΥΔΗΣ Εξαίρεση

Η χρήση όλων αυτών των χαρακτηριστικών αποδεικνύεται στο ακόλουθο παράδειγμα:

Προηγούμενα ιστολόγια έχουν δώσει επανειλημμένα παραδείγματα χρήσης παραμέτρων διαδικασίας και συνάρτησης. Οι παράμετροι είναι ένα μέσο μετάδοσης πληροφοριών προς και από μια ενότητα προγράμματος. Όταν χρησιμοποιούνται σωστά, κάνουν τις ενότητες πιο χρήσιμες και ευέλικτες.

Το PL/SQL σάς επιτρέπει να μεταβιβάζετε παραμέτρους στους δρομείς. Εκτελούν τις ίδιες λειτουργίες με τις παραμέτρους των μονάδων λογισμικού, καθώς και αρκετές πρόσθετες.

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

Ο αριθμός των παραμέτρων του δρομέα είναι απεριόριστος. Όταν καλείται OPEN, όλες οι παράμετροι (εκτός από αυτές που έχουν προεπιλεγμένες τιμές) πρέπει να καθοριστούν για τον κέρσορα.

Πότε ένας δρομέας απαιτεί παραμέτρους; Ο γενικός κανόνας εδώ είναι ο ίδιος όπως για τις διαδικασίες και τις συναρτήσεις: εάν ο δρομέας αναμένεται να χρησιμοποιηθεί σε διαφορετικά σημεία και με διαφορετικές τιμές στην ενότητα WHERE, θα πρέπει να οριστεί μια παράμετρος για αυτόν. Ας συγκρίνουμε δρομείς με και χωρίς την παράμετρο. Παράδειγμα δρομέα χωρίς παραμέτρους:

CURSOR joke_cur ΕΙΝΑΙ ΕΠΙΛΟΓΗ όνομα, κατηγορία, last_used_date ΑΠΟ Ανέκδοτα.

Το σύνολο αποτελεσμάτων του δρομέα περιλαμβάνει όλες τις εγγραφές στον πίνακα αστείων. Εάν χρειαζόμαστε μόνο ένα συγκεκριμένο υποσύνολο σειρών, η ενότητα WHERE περιλαμβάνεται στο ερώτημα:

CURSOR joke_cur ΕΙΝΑΙ ΕΠΙΛΟΓΗ όνομα, κατηγορία, last_used_date ΑΠΟ αστεία WHERE κατηγορία = "ΑΝΤΡΑΣ";

Για να εκτελέσουμε αυτήν την εργασία, δεν χρησιμοποιήσαμε παραμέτρους και δεν χρειάζονται. Σε αυτήν την περίπτωση, ο κέρσορας επιστρέφει όλες τις σειρές που ανήκουν σε μια συγκεκριμένη κατηγορία. Τι γίνεται όμως αν η κατηγορία αλλάζει κάθε φορά που αποκτάτε πρόσβαση σε αυτόν τον κέρσορα;

Δρομείς με παραμέτρους

Φυσικά, δεν θα ορίζαμε ξεχωριστό δρομέα για κάθε κατηγορία—κάτι που θα ήταν εντελώς ασυνεπές με τον τρόπο λειτουργίας της ανάπτυξης εφαρμογών βάσει δεδομένων. Χρειαζόμαστε μόνο έναν δρομέα, αλλά έναν για τον οποίο θα μπορούσαμε να αλλάξουμε την κατηγορία - και θα επέστρεφε τις απαιτούμενες πληροφορίες. Και η καλύτερη (αν και όχι η μόνη) λύση σε αυτό το πρόβλημα είναι να ορίσετε έναν παραμετροποιημένο δρομέα:

ΔΙΑΔΙΚΑΣΙΑ εξηγώ_ανέκδοτο (κύρια_κατηγορία_σε ΣΕ joke_category.category_id%TYPE) ΕΙΝΑΙ /* || Δρομέας με μια λίστα παραμέτρων που αποτελείται από || από μία παράμετρο συμβολοσειράς. */ CURSOR joke_cur (category_in IN VARCHAR2) IS SELECT name, category, last_used_date FROM Joke WHERE κατηγορία = UPPER (category_in); joke_rec joke_cur%ROWTYPE; BEGIN /* Τώρα, όταν ανοίγετε έναν δρομέα, ένα όρισμα μεταβιβάζεται σε αυτόν */ OPEN joke_cur (main_category_in); ΑΝΑΛΗΨΗ joke_cur ΣΕ joke_rec;

Ανάμεσα στο όνομα του δρομέα και τη λέξη-κλειδί IS υπάρχει τώρα μια λίστα παραμέτρων. Η κωδικοποιημένη τιμή HUSBAND στον όρο WHERE έχει αντικατασταθεί από μια αναφορά στην παράμετρο UPPER (category_in). Όταν ανοίγετε τον κέρσορα, μπορείτε να ορίσετε την τιμή σε HUSBAND , σύζυγος ή HuSbAnD - ο κέρσορας θα εξακολουθεί να λειτουργεί. Το όνομα της κατηγορίας για την οποία ο κέρσορας πρέπει να επιστρέψει σειρές πίνακα αστείων καθορίζεται στην πρόταση OPEN (σε παρένθεση) ως κυριολεκτική, σταθερά ή έκφραση. Όταν ανοίξει ο δρομέας, η εντολή SELECT αναλύεται και η παράμετρος συσχετίζεται με την τιμή. Στη συνέχεια, προσδιορίζεται το προκύπτον σύνολο σειρών και ο δρομέας είναι έτοιμος για ανάκτηση.

Άνοιγμα δρομέα με επιλογές

Ένας νέος δρομέας μπορεί να ανοίξει υποδεικνύοντας οποιαδήποτε κατηγορία:

OPEN joke_cur(Jokes_pkg.category); OPEN joke_cur("σύζυγος"); OPEN joke_cur("πολιτικός"); OPEN joke_cur (Jokes_pkg.relation || "-IN-LAW");

Οι παράμετροι του δρομέα χρησιμοποιούνται συχνότερα στον όρο WHERE, αλλά μπορούν να αναφέρονται αλλού στη δήλωση SELECT:

ΔΗΛΩΣΤΕ CURSOR joke_cur (category_in IN ARCHAR2) IS SELECT name, category_in, last_used_date FROM joke WHERE κατηγορία = UPPER (category_in);

Αντί να διαβάζουμε την κατηγορία από τον πίνακα, απλώς αντικαθιστούμε την παράμετρο category_in στη λίστα επιλογής. Το αποτέλεσμα παραμένει το ίδιο επειδή η ρήτρα WHERE περιορίζει την κατηγορία δείγματος στην τιμή της παραμέτρου.

Εύρος παραμέτρου δρομέα

Το εύρος μιας παραμέτρου δρομέα περιορίζεται σε αυτόν τον κέρσορα. Δεν είναι δυνατή η αναφορά μιας παραμέτρου δρομέα εκτός της εντολής SELECT που σχετίζεται με τον κέρσορα. Το παρακάτω απόσπασμα PL/SQL δεν μεταγλωττίζεται επειδή το όνομα_προγράμματος δεν είναι τοπική μεταβλητή στο μπλοκ. Αυτή είναι μια επίσημη παράμετρος δρομέα που ορίζεται μόνο μέσα στον κέρσορα:

ΔΗΛΩΣΤΕ CURSOR scariness_cur (program_name VARCHAR2) IS SELECT SUM (scary_level) total_scary_level FROM tales_from_the_crypt WHERE prog_name = program_name; BEGIN program_name:= "Η ΑΝΑΠΝΟΗ ΜΟΥΜΙΑ"; /* Μη έγκυρος σύνδεσμος */ OPEN scariness_cur (όνομα_προγράμματος); .... ΚΛΕΙΣΙΜΟ scariness_cur; ΤΕΛΟΣ;

Λειτουργίες παραμέτρων δρομέα

Η σύνταξη για τις παραμέτρους του δρομέα είναι πολύ παρόμοια με αυτή των διαδικασιών και των συναρτήσεων - εκτός από το ότι οι παράμετροι του δρομέα μπορούν να είναι μόνο παράμετροι IN. Οι παράμετροι του δρομέα δεν μπορούν να ρυθμιστούν σε λειτουργίες OUT ή IN OUT. Αυτές οι λειτουργίες επιτρέπουν τη μετάδοση και την επιστροφή τιμών από διαδικασίες, κάτι που δεν έχει νόημα για έναν δρομέα. Υπάρχει μόνο ένας τρόπος για να λάβετε πληροφορίες από τον κέρσορα: να ανακτήσετε μια εγγραφή και να αντιγράψετε τις τιμές από τη λίστα στηλών στην ενότητα INTO

Προεπιλεγμένες τιμές παραμέτρων

Στις παραμέτρους του δρομέα μπορούν να εκχωρηθούν προεπιλεγμένες τιμές. Ένα παράδειγμα δρομέα με προεπιλεγμένη τιμή παραμέτρου:

CURSOR emp_cur (emp_id_in ΑΡΙΘΜΟΣ:= 0) ΕΙΝΑΙ SELECT staff_id, emp_name FROM υπάλληλος WHERE staff_id = emp_id_in;

Επειδή η παράμετρος emp_id_in έχει μια προεπιλεγμένη τιμή, μπορεί να παραλειφθεί στην εντολή FETCH. Σε αυτήν την περίπτωση, ο κέρσορας θα επιστρέψει πληροφορίες για τον υπάλληλο με κωδικό 0.

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

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

Υπάρχει μια διαδικασία που κάνει ορισμένα πράγματα που μια κανονική συνάρτηση SQL δεν μπορεί να κάνει, όπως υπολογισμούς και εισαγωγή με βάση αυτούς τους υπολογισμούς. Και το εκκινείτε, για παράδειγμα ως εξής:

EXEC test_PROCEDURE par1, par2

Με άλλα λόγια, το εκτελείτε μόνο με τις παραμέτρους που καθορίστηκαν, αλλά αν χρειαστεί να εκτελέσετε αυτήν τη διαδικασία, ας πούμε, 100, 200 ή ακόμα περισσότερες φορές, τότε θα συμφωνήσετε ότι αυτό δεν είναι πολύ βολικό, π.χ. για πολύ καιρό. Θα ήταν πολύ πιο εύκολο αν εκτελούσαμε τη διαδικασία σαν μια κανονική συνάρτηση σε ένα επιλεγμένο ερώτημα, όπως αυτό:

ΕΠΙΛΕΞΤΕ my_fun(id) ΑΠΟ test_table

Με άλλα λόγια, η συνάρτηση θα λειτουργεί για κάθε εγγραφή του πίνακα test_table, αλλά όπως γνωρίζετε, η διαδικασία δεν μπορεί να χρησιμοποιηθεί με αυτόν τον τρόπο. Αλλά υπάρχει ένας τρόπος που θα μας βοηθήσει να επιτύχουμε το σχέδιό μας, ή μάλλον, ακόμη και με δύο τρόπους: ο πρώτος είναι η χρήση ενός δρομέα και ενός βρόχου και ο δεύτερος είναι απλά η χρήση ενός βρόχου, αλλά χωρίς δρομέα. Και οι δύο επιλογές υποδηλώνουν ότι θα δημιουργήσουμε μια πρόσθετη διαδικασία, την οποία θα ξεκινήσουμε αργότερα.

Σημείωση!Θα γράψουμε όλα τα παραδείγματα στο MSSql 2008 DBMS χρησιμοποιώντας το Management Studio. Επίσης, όλες οι ενέργειες που αναφέρονται παρακάτω απαιτούν τις απαραίτητες γνώσεις σε SQL, ή ακριβέστερα στον προγραμματισμό στο Transact-SQL. Μπορώ να προτείνω να ξεκινήσετε με την ανάγνωση του παρακάτω υλικού:

Και ας ξεκινήσουμε, και πριν γράψουμε τη διαδικασία, ας δούμε τα δεδομένα πηγής του παραδείγματός μας.

Ας υποθέσουμε ότι υπάρχει ένας πίνακας test_table

ΔΗΜΙΟΥΡΓΙΑ ΠΙΝΑΚΑΣ

Είναι απαραίτητο να εισαγάγετε δεδομένα σε αυτό, με βάση ορισμένους υπολογισμούς που θα εκτελέσει η διαδικασία my_proc_test, σε αυτήν την περίπτωση απλώς εισάγει δεδομένα, αλλά στην πράξη μπορείτε να χρησιμοποιήσετε τη δική σας διαδικασία, η οποία μπορεί να εκτελέσει πολλούς υπολογισμούς, οπότε στην περίπτωσή μας αυτή η συγκεκριμένη διαδικασία δεν είναι σημαντική, είναι απλώς ένα παράδειγμα. Λοιπόν, ας το δημιουργήσουμε:

ΔΗΜΙΟΥΡΓΙΑ ΔΙΑΔΙΚΑΣΙΑΣ. (@number numeric, @pole1 varchar(50), @pole2 varchar(50)) AS BEGIN INSERT INTO dbo.test_table (number, pole1, pole2) ΤΙΜΕΣ (@number, @pole1, @pole2) END GO

Απλώς παίρνει τρεις παραμέτρους και τις εισάγει στον πίνακα.

Και ας πούμε αυτή τη διαδικασία, πρέπει να την εκτελέσουμε όσες φορές υπάρχουν σειρές σε κάποιον πίνακα ή προβολή (VIEWS), με άλλα λόγια, να την εκτελέσουμε μαζικά για κάθε γραμμή πηγής.

Και για παράδειγμα, ας δημιουργήσουμε μια τέτοια πηγή, θα έχουμε έναν απλό πίνακα test_table_time, αλλά για εσάς μπορεί να είναι, όπως είπα ήδη η πηγή μου, για παράδειγμα ένας προσωρινός πίνακας ή προβολή:

ΔΗΜΙΟΥΡΓΙΑ ΠΙΝΑΚΑΣ

Ας το συμπληρώσουμε με δεδομένα δοκιμής:

Και τώρα η διαδικασία μας πρέπει να εκτελεστεί για κάθε σειρά, π.χ. τρεις φορές με διαφορετικές παραμέτρους. Όπως καταλαβαίνετε, οι τιμές αυτών των πεδίων είναι οι παράμετροί μας, με άλλα λόγια, εάν εκτελούσαμε τη διαδικασία μας χειροκίνητα, θα έμοιαζε με αυτό:

exec my_proc_test 1, 'pole1_str1', 'pole2_str1'

Και ούτω καθεξής άλλες τρεις φορές, με τις κατάλληλες παραμέτρους.

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

Πρώτη επιλογή.

Χρήση δρομέα και βρόχου σε μια διαδικασία

Ας μπούμε κατευθείαν στο θέμα και ας γράψουμε τη διαδικασία ( my_proc_test_all), σχολίασα τον κώδικα όπως πάντα:

ΔΗΜΙΟΥΡΓΙΑ ΔΙΑΔΙΚΑΣΙΑΣ. AS --δηλώστε μεταβλητές DECLARE @number bigint DECLARE @pole1 varchar(50) DECLARE @pole2 varchar(50) --δηλώστε έναν δρομέα DECLARE my_cur CURSOR FOR SELECT number, pole1, pole2 FROM test_table_vrem --open the cursor -- OPad EN τα δεδομένα των πρώτων γραμμών στις μεταβλητές μας FETCH NEXT FROM my_cur INTO @number, @pole1, @pole2 --αν υπάρχουν δεδομένα στον δρομέα, τότε πηγαίνετε σε έναν βρόχο --και περιστρέψτε εκεί μέχρι να μην υπάρχουν άλλες γραμμές στο δρομέας WHILE @@FETCH_STATUS = 0 BEGIN --για κάθε επανάληψη του βρόχου, ξεκινάμε την κύρια διαδικασία με τις απαραίτητες παραμέτρους exec dbo.my_proc_test @number, @pole1, @pole2 --διαβάζουμε την επόμενη γραμμή του δρομέα FETCH NEXT FROM my_cur INTO @number, @pole1, @pole2 ΤΕΛΟΣ --κλείστε τον κέρσορα ΚΛΕΙΣΙΜΟ my_cur ΑΠΟΣΤΟΛΗ my_cur GO

Και τώρα το μόνο που έχουμε να κάνουμε είναι να το καλέσουμε και να ελέγξουμε το αποτέλεσμα:

Πριν από την εκτέλεση της διαδικασίας SELECT * FROM test_table --καλέστε τη διαδικασία EXEC dbo.my_proc_test_all --αφού εκτελεστεί η διαδικασία SELECT * FROM test_table

Όπως μπορείτε να δείτε, όλα λειτούργησαν όπως θα έπρεπε, με άλλα λόγια, η διαδικασία my_proc_test λειτούργησε και τις τρεις φορές, και εκτελέσαμε την πρόσθετη διαδικασία μόνο μία φορά.

Δεύτερη επιλογή.

Χρησιμοποιούμε μόνο έναν βρόχο στη διαδικασία

Θα πω αμέσως ότι αυτό απαιτεί αρίθμηση σειρών στον προσωρινό πίνακα, δηλ. Κάθε γραμμή πρέπει να είναι αριθμημένη, για παράδειγμα 1, 2, 3· στον προσωρινό μας πίνακα αυτό το πεδίο είναι αριθμός.

Σύνταξη διαδικασίας my_proc_test_all_v2

ΔΗΜΙΟΥΡΓΙΑ ΔΙΑΔΙΚΑΣΙΑΣ. AS --declare variables DECLARE @number bigint DECLARE @pole1 varchar(50) DECLARE @pole2 varchar(50) DECLARE @cnt int DECLARE @i int --βρείτε τον αριθμό των σειρών στον προσωρινό πίνακα SELECT @cnt=count(* ) FROM test_table_vrem - -ορίστε την αρχική τιμή του αναγνωριστικού SET @i=1 WHILE @cnt >= @i BEGIN -- αντιστοιχίστε τιμές στις παραμέτρους μας SELECT @number=number, @pole1= pole1, @pole2=pole2 FROM test_table_vrem WHERE αριθμός = @I --για κάθε επανάληψη του βρόχου, ξεκινάμε την κύρια διαδικασία με τις απαραίτητες παραμέτρους EXEC dbo.my_proc_test @number, @pole1, @pole2 --αυξάνουμε το σύνολο βημάτων @i= @i+1 ΤΕΛΟΣ ΠΗΓΑΙΝΩ

Και ελέγχουμε το αποτέλεσμα, αλλά πρώτα θα καθαρίσουμε τον πίνακα μας, αφού μόλις τον συμπληρώσαμε χρησιμοποιώντας τη διαδικασία my_proc_test_all:

Εκκαθαρίστε τον πίνακα DELETE test_table --πριν εκτελέσετε τη διαδικασία SELECT * FROM test_table --καλώντας τη διαδικασία EXEC dbo.my_proc_test_all_v2 --μετά την εκτέλεση της διαδικασίας SELECT * FROM test_table

Όπως ήταν αναμενόμενο, το αποτέλεσμα είναι το ίδιο, αλλά χωρίς χρήση δρομέων. Εναπόκειται σε εσάς να αποφασίσετε ποια επιλογή θα χρησιμοποιήσετε, η πρώτη επιλογή είναι καλή επειδή, κατ 'αρχήν, δεν απαιτείται αρίθμηση, αλλά όπως γνωρίζετε, οι δρομείς λειτουργούν για αρκετό καιρό εάν υπάρχουν πολλές γραμμές στον κέρσορα και η δευτερη επιλογη ειναι καλη γιατι μου φαινεται οτι θα δουλεψει πιο γρηγορα, παλι αν ειναι πολλες γραμμες αλλα χρειαζεται αρίθμηση, προσωπικα μου αρεσει η επιλογη με δρομο, αλλα γενικα ειναι στο χερι σου, μπορεις βρείτε κάτι πιο βολικό, μόλις έδειξα τα βασικά για το πώς μπορείτε να εφαρμόσετε την εργασία. Καλή τύχη!

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

Δεδομένου ότι οι δρομείς αποτελούν μέρος μιας αποθηκευμένης διαδικασίας, σε αυτό το άρθρο θα εξετάσουμε την HP με περισσότερες λεπτομέρειες. Συγκεκριμένα, πώς να εξαγάγετε ένα σύνολο δεδομένων από την HP.

Τι είναι ο δρομέας;

Ένας δρομέας δεν μπορεί να χρησιμοποιηθεί από μόνος του στη MySQL. Είναι ένα σημαντικό συστατικό των αποθηκευμένων διαδικασιών. Θα συνέκρινα έναν δρομέα με έναν "δείκτη" σε C/C++ ή έναν επαναλήπτη σε μια δήλωση PHP foreach.

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

Αυτή η λειτουργία επεξεργασίας εγγραφών μπορεί επίσης να γίνει στο επίπεδο PHP, το οποίο μειώνει σημαντικά τον όγκο των δεδομένων που διαβιβάζονται στο επίπεδο PHP, καθώς μπορούμε απλά να επιστρέψουμε την επεξεργασμένη σύνοψη/στατιστικό αποτέλεσμα πίσω (άρα εξαλείφεται η επεξεργασία επιλογής - για κάθε από την πλευρά του πελάτη) .

Δεδομένου ότι ο κέρσορας υλοποιείται σε μια αποθηκευμένη διαδικασία, έχει όλα τα πλεονεκτήματα (και μειονεκτήματα) που είναι εγγενή στην HP (έλεγχος πρόσβασης, προ-μεταγλώττιση, δυσκολία εντοπισμού σφαλμάτων κ.λπ.)

Μπορείτε να βρείτε την επίσημη τεκμηρίωση για τους δρομείς εδώ. Περιγράφει τέσσερις εντολές που σχετίζονται με τη δήλωση, το άνοιγμα, το κλείσιμο και την ανάκτηση του δρομέα. Όπως αναφέρθηκε, θα καλύψουμε επίσης κάποιες άλλες αποθηκευμένες δηλώσεις διαδικασίας. Ας αρχίσουμε.

Παράδειγμα πρακτικής εφαρμογής

Η προσωπική μου ιστοσελίδα έχει μια σελίδα με αποτελέσματα αγώνων για την αγαπημένη μου ομάδα του ΝΒΑ: τους Λέικερς.

Η δομή του πίνακα αυτής της σελίδας είναι αρκετά απλή:

Εικ. 1. Δομή του πίνακα αποτελεσμάτων του αγώνα Lakers

Συμπληρώνω αυτόν τον πίνακα από το 2008. Μερικά από τα τελευταία αποτελέσματα αγώνων των Λέικερς για τη σεζόν 2013-14 είναι παρακάτω:

Ρύζι. 2. Πίνακας αποτελεσμάτων αγώνων Lakers (μερικός) τη σεζόν 2013-2014

(Χρησιμοποιώ το MySQL Workbench ως εργαλείο GUI για τη διαχείριση της βάσης δεδομένων MySQL. Μπορείτε να χρησιμοποιήσετε άλλο εργαλείο της επιλογής σας).

Λοιπόν, πρέπει να ομολογήσω ότι οι μπασκετμπολίστες των Λέικερς δεν παίζουν πολύ καλά τον τελευταίο καιρό. 6 σερί ήττες στις 15 Ιανουαρίου. αυτά τα όρισα" 6 σερί ήττες", μετρώντας με μη αυτόματο τρόπο πόσους αγώνες στη σειρά, ξεκινώντας από την τρέχουσα ημερομηνία (και μέχρι τα προηγούμενα παιχνίδια) έχουν τιμή winlose "L" (ήττα).

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

Μπορούμε να κάνουμε το ίδιο με μία μόνο πρόταση SQL; Δεν είμαι ειδικός στην SQL, επομένως δεν μπορούσα να καταλάβω πώς να επιτύχω το επιθυμητό αποτέλεσμα (" 6 σερί ήττες") μέσω μιας μεμονωμένης δήλωσης SQL. Οι απόψεις του γκουρού θα είναι πολύ πολύτιμες για μένα - αφήστε τις στα σχόλια παρακάτω.

Μπορούμε να το κάνουμε αυτό μέσω PHP; Ναι σίγουρα. Μπορούμε να λάβουμε τα δεδομένα του παιχνιδιού (συγκεκριμένα, τη στήλη winlos) για εκείνη τη σεζόν και να επαναλάβουμε τα αρχεία για να υπολογίσουμε τη διάρκεια του τρέχοντος σερί νικών/ήττων.

Αλλά για να γίνει αυτό, θα έπρεπε να καλύψουμε όλα τα δεδομένα για εκείνη τη χρονιά και τα περισσότερα δεδομένα θα ήταν άχρηστα για εμάς (δεν είναι πολύ πιθανό κάποια ομάδα να έχει σερί μεγαλύτερο από 20+ παιχνίδια στη σειρά μια κανονική περίοδος 82 αγώνων).

Ωστόσο, δεν γνωρίζουμε με βεβαιότητα πόσες εγγραφές πρέπει να ανακτηθούν στην PHP για να προσδιοριστεί μια σειρά. Επομένως, δεν μπορούμε να κάνουμε χωρίς να εξάγουμε άσκοπα περιττά δεδομένα. Και τέλος, αν ο τρέχων αριθμός νικών/ήττων στη σειρά είναι το μόνο πράγμα που θέλουμε να μάθουμε από αυτόν τον πίνακα, γιατί θα χρειαστεί να εξαγάγουμε όλες τις σειρές δεδομένων;

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

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

Πώς μπορούμε λοιπόν να το κάνουμε αυτό καλύτερα;

Χρήση δρομέα σε αποθηκευμένη διαδικασία

Όπως ίσως μαντέψατε από τον τίτλο αυτού του άρθρου, η καλύτερη εναλλακτική (κατά τη γνώμη μου) για την επίλυση αυτού του προβλήματος είναι να χρησιμοποιήσετε έναν δρομέα σε μια αποθηκευμένη διαδικασία.

Ας δημιουργήσουμε την πρώτη HP στο MySQL Workbench:

DELIMITER $$ ΔΗΜΙΟΥΡΓΙΑ DEFINER=`root`@`localhost` ΔΙΑΔΙΚΑΣΙΑ `Strak`(σε cur_year int, out longeststreak int, out status char(1)) BEGIN δήλωση current_win char(1); Δηλώστε current_streak int; δήλωση τρέχουσας_κατάστασης char(1); δηλώστε δρομέα για επιλέξτε winlose από lakers όπου έτος=cur_έτος και winlose<>"" παραγγελία κατά id desc; ορισμός τρέχουσας_γραμμής=0; ανοιχτή κουρτίνα? fetch cur στο current_win. ορίστε current_streak = current_streak +1; start_loop: επαναφορά βρόχου σε τρέχουσα κατάσταση. εάν τρέχουσα_κατάσταση<>current_win και μετά αφήστε το start_loop. αλλιώς ορίστε current_streak=current_streak+1; τέλος εαν; βρόχος τέλος? Κλείσιμο cur? επιλέξτε current_streak σε longeststreak. επιλέξτε Current_win σε `status`. ΤΕΛΟΣ

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

Στο σώμα της HP δηλώσαμε επίσης αρκετές τοπικές μεταβλητές για τη σειρά αποτελεσμάτων (νίκες ή ήττες, τρέχον_νίκη), την τρέχουσα σειρά και την τρέχουσα κατάσταση νίκης/ήττας ενός συγκεκριμένου αγώνα:

Αυτή η γραμμή είναι η δήλωση του δρομέα. Έχουμε δηλώσει έναν δρομέα με το όνομα cur και ένα σύνολο δεδομένων που σχετίζονται με αυτόν τον δρομέα, που είναι η κατάσταση νίκης/ήττας για αυτούς τους αγώνες (η τιμή της στήλης winlose μπορεί να είναι είτε "W" ή "L", αλλά όχι κενή) στο ένα συγκεκριμένο έτος που ταξινομούνται κατά αναγνωριστικό (τα τελευταία παιχνίδια που παίχτηκαν θα έχουν υψηλότερο αναγνωριστικό) με φθίνουσα σειρά.

Αν και δεν είναι ορατό, μπορούμε να φανταστούμε ότι αυτό το σύνολο δεδομένων θα περιέχει μια ακολουθία τιμών "L" και "W". Με βάση τα δεδομένα που φαίνονται στο Σχήμα 2, θα πρέπει να είναι ως εξής: "LLLLLLWLL..." (6 τιμές "L", 1 "W" κ.λπ.)

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

Αφού φορτωθούν τα πρώτα δεδομένα, ο κέρσορας μετακινείται στην επόμενη εγγραφή. Έτσι, η συμπεριφορά του δρομέα είναι παρόμοια με μια ουρά που επαναλαμβάνεται μέσω ενός συνόλου δεδομένων χρησιμοποιώντας το σύστημα FIFO (First In First Out). Αυτό ακριβώς χρειαζόμαστε.

Αφού λάβουμε την τρέχουσα κατάσταση νίκης/ήττας και τον αριθμό των διαδοχικών πανομοιότυπων στοιχείων στο σετ, συνεχίζουμε να κάνουμε βρόχο μέσω του υπόλοιπου συνόλου δεδομένων. Σε κάθε επανάληψη του βρόχου, ο κέρσορας θα «πηδά» στην επόμενη εγγραφή μέχρι να σπάσουμε τον βρόχο ή μέχρι να επαναληφθούν όλες οι εγγραφές.

Εάν η κατάσταση του επόμενου ρεκόρ είναι ίδια με το τρέχον διαδοχικό σετ νικών/ήττων, σημαίνει ότι το σερί συνεχίζεται, τότε αυξάνουμε τον αριθμό των συνεχόμενων νικών (ή ήττων) κατά 1 ακόμη και συνεχίζουμε να κάνουμε βρόχο στα δεδομένα.

Εάν η κατάσταση είναι διαφορετική, σημαίνει ότι το σερί έχει σπάσει και μπορούμε να σταματήσουμε τον κύκλο. Τέλος, κλείνουμε τον κέρσορα και αφήνουμε τα αρχικά δεδομένα. Μετά από αυτό, εμφανίζεται το αποτέλεσμα.

Για να ελέγξουμε τη λειτουργία αυτής της HP, μπορούμε να γράψουμε ένα σύντομο σενάριο PHP:

exec("call streak(2013, @longeststreak, @status)"); $res=$cn->query("select @longeststreak, @status")->fetchAll(); var_dump($res); //Αποθέστε την έξοδο εδώ για να λάβετε μια μη επεξεργασμένη προβολή της εξόδου $win=$res["@status"]="L"?"Loss":"Win"; $streak=$res["@longeststreak"]; echo "Οι Λέικερς είναι τώρα $σερί διαδοχικές $win.n";

Το αποτέλεσμα της επεξεργασίας θα πρέπει να μοιάζει με το ακόλουθο σχήμα:

Έξοδος ενός συνόλου δεδομένων από μια αποθηκευμένη διαδικασία

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

Ο χρήστης μπορεί να θέλει να λάβει περισσότερες πληροφορίες χρησιμοποιώντας την HP που δημιουργήσαμε προηγουμένως από μια απλή σειρά από νίκες/ήττες για το έτος. για παράδειγμα, μπορούμε να δημιουργήσουμε έναν πίνακα που θα εμφανίζει σειρές νικών/ήττων για διαφορετικά έτη:

ΕΤΟΣ Νίκη/ήττα Ράβδωση
2013 μεγάλο 6
2012 μεγάλο 4
2011 μεγάλο 2

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

Οι αποθηκευμένες διαδικασίες της MySQL μπορούν να επιστρέψουν μόνο βαθμωτές τιμές (ακέραιος, συμβολοσειρά κ.λπ.), σε αντίθεση με τις δηλώσεις επιλογής ... από ... (τα αποτελέσματα μετατρέπονται σε σύνολο δεδομένων). Το πρόβλημα είναι ότι ο πίνακας στον οποίο θέλουμε να λάβουμε τα αποτελέσματα δεν υπάρχει στην υπάρχουσα δομή βάσης δεδομένων· έχει μεταγλωττιστεί από τα αποτελέσματα της επεξεργασίας της αποθηκευμένης διαδικασίας.

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

Πρώτα θα δημιουργήσουμε ένα δεύτερο HP, ο κωδικός του οποίου φαίνεται παρακάτω:

DELIMITER $$ CREATE DEFINER=`root`@`%` PROCEDURE `yearly_streak`() start declare cur_year, max_year, min_year int; επιλέξτε μέγ. ΑΠΟΣΤΟΛΗ ΠΡΟΣΩΡΙΝΟΥ ΠΙΝΑΚΑ ΑΝ ΥΠΑΡΧΕΙ yearly_streak; ΔΗΜΙΟΥΡΓΙΑ ΠΡΟΣΩΡΙΝΟΥ ΠΙΝΑΚΑΣ yearly_streak (season int, streak int, win char(1)); ορίστε cur_year=max_year; year_loop: βρόχος εάν cur_year

Μερικές σημαντικές σημειώσεις για τον παραπάνω κώδικα:

  1. Καθορίζουμε το αρχαιότερο και το πιο πρόσφατο έτος για το δείγμα από τον πίνακα των λέικερ.
  2. Δημιουργούμε έναν προσωρινό πίνακα για την αποθήκευση εξερχόμενων δεδομένων με την απαραίτητη δομή (σεζόν, σερί, νίκη).
  3. Στον βρόχο, εκτελούμε πρώτα την HP που δημιουργήθηκε προηγουμένως με τις απαραίτητες παραμέτρους (σειρά κλήσης(cur_year, @l, @s);), στη συνέχεια καταγράφουμε τα δεδομένα που επιστράφηκαν και τα εισάγουμε σε έναν προσωρινό πίνακα ( εισαγάγετε σε τιμές yearly_streak (cur_year, @l, @s););
  4. Τέλος, επιλέγουμε από τον προσωρινό πίνακα και επιστρέφουμε το σύνολο δεδομένων και μετά κάνουμε κάποια ρύθμιση ( ΑΠΟΣΤΟΛΗ ΠΡΟΣΩΡΙΝΟΥ ΠΙΝΑΚΑ ΑΝ ΥΠΑΡΧΕΙ yearly_streak;).

Για να λάβουμε τα αποτελέσματα, δημιουργούμε ένα άλλο μικρό σενάριο PHP, ο κώδικας του οποίου φαίνεται παρακάτω:

query("call yearly_streak")->fetchAll(); foreach ($res ως $r) ( echo sprintf("Στο έτος %d, οι μεγαλύτερες σειρές W/L είναι %d %sn", $r["season"], $r["streak"], $r[ "νίκη"]);)

Τα εμφανιζόμενα αποτελέσματα θα μοιάζουν κάπως έτσι:

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

Έννοια του δρομέα

Ένα ερώτημα σε σχέση με μια σχεσιακή βάση δεδομένων επιστρέφει συνήθως πολλές σειρές (εγγραφές) δεδομένων, αλλά η εφαρμογή επεξεργάζεται μόνο μία εγγραφή κάθε φορά. Ακόμα κι αν ασχολείται με πολλές σειρές ταυτόχρονα (για παράδειγμα, εμφανίζει δεδομένα με τη μορφή υπολογιστικών φύλλων), ο αριθμός τους εξακολουθεί να είναι περιορισμένος. Επιπλέον, κατά την τροποποίηση, τη διαγραφή ή την προσθήκη δεδομένων, η μονάδα εργασίας είναι η σειρά. Σε αυτήν την περίπτωση, η έννοια του δρομέα έρχεται στο προσκήνιο και σε αυτό το πλαίσιο, ο κέρσορας είναι ένας δείκτης σε μια σειρά.

Ένας δρομέας στο SQL είναι μια περιοχή στη μνήμη της βάσης δεδομένων που έχει σχεδιαστεί για να διατηρεί την τελευταία πρόταση SQL. Εάν η τρέχουσα δήλωση είναι ένα ερώτημα βάσης δεδομένων, μια σειρά δεδομένων ερωτήματος που ονομάζεται τρέχουσα τιμή ή τρέχουσα γραμμή δρομέα, αποθηκεύεται επίσης στη μνήμη. Η καθορισμένη περιοχή στη μνήμη ονομάζεται και είναι προσβάσιμη σε προγράμματα εφαρμογών.

Συνήθως, οι δρομείς χρησιμοποιούνται για να επιλέξουν από μια βάση δεδομένων ένα υποσύνολο των πληροφοριών που είναι αποθηκευμένες σε αυτήν. Ανά πάσα στιγμή, μια γραμμή δρομέα μπορεί να ελεγχθεί από το πρόγραμμα εφαρμογής. Οι δρομείς χρησιμοποιούνται συχνά σε δηλώσεις SQL που είναι ενσωματωμένες σε προγράμματα εφαρμογών γραμμένων σε διαδικαστικές γλώσσες. Μερικά από αυτά δημιουργούνται έμμεσα από τον διακομιστή της βάσης δεδομένων, ενώ άλλα ορίζονται από προγραμματιστές.

Σύμφωνα με το πρότυπο SQL, όταν εργάζεστε με δρομείς, μπορούν να διακριθούν οι ακόλουθες κύριες ενέργειες:

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

Ο ορισμός του δρομέα μπορεί να διαφέρει ελαφρώς μεταξύ των υλοποιήσεων. Για παράδειγμα, μερικές φορές ένας προγραμματιστής πρέπει να ελευθερώσει ρητά τη μνήμη που έχει εκχωρηθεί για έναν δρομέα. Μετά απελευθερώστε τον κέρσοραΗ σχετική μνήμη ελευθερώνεται επίσης. Αυτό καθιστά δυνατή την επαναχρησιμοποίηση του ονόματός του. Σε άλλες υλοποιήσεις όταν κλείνοντας τον κέρσοραΗ απελευθέρωση μνήμης συμβαίνει σιωπηρά. Αμέσως μετά την ανάκτηση, γίνεται διαθέσιμο για άλλες επεμβάσεις: ανοίγοντας άλλον δρομέακαι τα λοιπά.

Σε ορισμένες περιπτώσεις, η χρήση δρομέα είναι αναπόφευκτη. Ωστόσο, εάν είναι δυνατόν, αυτό θα πρέπει να αποφεύγεται και να λειτουργεί με τυπικές εντολές επεξεργασίας δεδομένων: SELECT, UPDATE, INSERT, DELETE. Εκτός από το γεγονός ότι οι δρομείς δεν επιτρέπουν λειτουργίες τροποποίησης σε ολόκληρο τον όγκο δεδομένων, η ταχύτητα εκτέλεσης εργασιών επεξεργασίας δεδομένων με χρήση δρομέα είναι αισθητά χαμηλότερη από αυτή των τυπικών εργαλείων SQL.

Υλοποίηση δρομέων σε περιβάλλον MS SQL Server

Ο SQL Server υποστηρίζει τρεις τύπους δρομέων:

  • Οι δρομείς SQL χρησιμοποιούνται κυρίως σε ενεργοποιητές, αποθηκευμένες διαδικασίες και σενάρια.
  • Οι δρομείς διακομιστή λειτουργούν στον διακομιστή και υλοποιούν τη διεπαφή προγραμματισμού εφαρμογών για ODBC, OLE DB, DB_Library.
  • Οι δρομείς πελάτη εφαρμόζονται στον ίδιο τον πελάτη. Λαμβάνουν ολόκληρο το σύνολο αποτελεσμάτων των σειρών από τον διακομιστή και το αποθηκεύουν τοπικά, γεγονός που επιταχύνει την επεξεργασία δεδομένων μειώνοντας τον χαμένο χρόνο που δαπανάται σε λειτουργίες δικτύου.

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

Στον SQL Server, οι τύποι δρομέα διαφέρουν ως προς τις δυνατότητες που παρέχουν. Ο τύπος του δρομέα καθορίζεται στο στάδιο της δημιουργίας του και δεν μπορεί να αλλάξει. Ορισμένοι τύποι δρομέων μπορούν να ανιχνεύσουν αλλαγές που έγιναν από άλλους χρήστες σε σειρές που περιλαμβάνονται στο σύνολο αποτελεσμάτων. Ωστόσο, ο SQL Server παρακολουθεί τις αλλαγές σε τέτοιες σειρές μόνο κατά την πρόσβαση στη σειρά και δεν επιτρέπει την τροποποίηση των αλλαγών αφού έχει ήδη διαβαστεί η σειρά.

Οι δρομείς χωρίζονται σε δύο κατηγορίες: ακολουθητικόςκαι κυλιόμενο. Συνεχήςσας επιτρέπουν να επιλέξετε δεδομένα μόνο προς μία κατεύθυνση - από την αρχή μέχρι το τέλος. Δρομείς με δυνατότητα κύλισηςπαρέχουν μεγαλύτερη ελευθερία δράσης - είναι δυνατό να μετακινηθείτε και προς τις δύο κατευθύνσεις και να μεταβείτε σε μια αυθαίρετη σειρά του συνόλου αποτελεσμάτων του δρομέα. Εάν το πρόγραμμα μπορεί να τροποποιήσει τα δεδομένα στα οποία δείχνει ο κέρσορας, ονομάζεται κύλιση και τροποποιήσιμο. Μιλώντας για δρομείς, δεν πρέπει να ξεχνάμε την απομόνωση συναλλαγών. Όταν ένας χρήστης τροποποιεί μια εγγραφή, ένας άλλος τη διαβάζει χρησιμοποιώντας το δικό του δρομέα και επιπλέον, μπορεί να τροποποιήσει την ίδια εγγραφή, γεγονός που καθιστά απαραίτητη τη διατήρηση της ακεραιότητας των δεδομένων.

Ο SQL Server υποστηρίζει στατικά, δυναμικά, ακολουθητικόςκαι ελέγχεται από ένα σύνολο πλήκτρων.

Στο σχήμα με στατικό δρομέαΟι πληροφορίες διαβάζονται από τη βάση δεδομένων μία φορά και αποθηκεύονται ως στιγμιότυπο (κάποια χρονική στιγμή), επομένως οι αλλαγές που έγιναν στη βάση δεδομένων από άλλο χρήστη δεν είναι ορατές. Για λίγο ανοίγοντας τον κέρσοραο διακομιστής θέτει ένα κλείδωμα σε όλες τις σειρές που περιλαμβάνονται στο πλήρες σύνολο αποτελεσμάτων του. Στατικός κέρσοραςδεν αλλάζει μετά τη δημιουργία και εμφανίζει πάντα το σύνολο δεδομένων που υπήρχε κατά το άνοιγμά του.

Εάν άλλοι χρήστες αλλάξουν τα δεδομένα που περιλαμβάνονται στον δρομέα στον πίνακα προέλευσης, αυτό δεν θα επηρεάσει το στατικό δρομέα.

ΣΕ στατικό δρομέαΔεν είναι δυνατή η πραγματοποίηση αλλαγών, επομένως ανοίγει πάντα σε λειτουργία μόνο για ανάγνωση.

Δυναμικός κέρσοραςδιατηρεί τα δεδομένα σε «ζωντανή» κατάσταση, αλλά αυτό απαιτεί πόρους δικτύου και λογισμικού. Χρησιμοποιώντας δυναμικούς δρομείςδεν δημιουργείται πλήρες αντίγραφο των δεδομένων προέλευσης, αλλά εκτελείται μια δυναμική επιλογή από τους πίνακες προέλευσης μόνο όταν ο χρήστης έχει πρόσβαση σε συγκεκριμένα δεδομένα. Κατά τη διάρκεια της ανάκτησης, ο διακομιστής κλειδώνει τις σειρές και τυχόν αλλαγές που κάνει ο χρήστης στο πλήρες σύνολο αποτελεσμάτων του δρομέα θα είναι ορατές στον κέρσορα. Ωστόσο, εάν κάποιος άλλος χρήστης έχει κάνει αλλαγές μετά την ανάκτηση των δεδομένων από τον κέρσορα, αυτές δεν θα αντικατοπτρίζονται στον κέρσορα.

Δρομέας που ελέγχεται από ένα σύνολο πλήκτρων, βρίσκεται στη μέση μεταξύ αυτών των άκρων. Τα αρχεία προσδιορίζονται τη στιγμή της δειγματοληψίας και έτσι οι αλλαγές παρακολουθούνται. Αυτός ο τύπος δρομέα είναι χρήσιμος κατά την εφαρμογή κύλισης προς τα πίσω - τότε οι προσθήκες και οι διαγραφές σειρών δεν είναι ορατές μέχρι να ενημερωθούν οι πληροφορίες και το πρόγραμμα οδήγησης επιλέγει μια νέα έκδοση της εγγραφής εάν έχουν γίνει αλλαγές σε αυτήν.

Διαδοχικοί δρομείςδεν επιτρέπεται η ανάκτηση δεδομένων προς την αντίστροφη κατεύθυνση. Ο χρήστης μπορεί να επιλέξει μόνο σειρές από την αρχή έως το τέλος του δρομέα. Σειριακός δρομέαςδεν αποθηκεύει ένα σύνολο από όλες τις σειρές. Διαβάζονται από τη βάση δεδομένων αμέσως μόλις επιλεγούν στον κέρσορα, ο οποίος επιτρέπει σε όλες τις αλλαγές που γίνονται από τους χρήστες στη βάση δεδομένων να αντικατοπτρίζονται δυναμικά χρησιμοποιώντας εντολές INSERT, UPDATE, DELETE. Ο κέρσορας δείχνει την πιο πρόσφατη κατάσταση των δεδομένων.

Στατικοί δρομείςπαρέχει μια σταθερή προβολή των δεδομένων. Είναι καλές για συστήματα "αποθήκευσης" πληροφοριών: εφαρμογές για συστήματα αναφοράς ή για στατιστικούς και αναλυτικούς σκοπούς. Εκτός, στατικό δρομέααντιμετωπίζει καλύτερα από άλλους με τη δειγματοληψία μεγάλων ποσοτήτων δεδομένων. Αντίθετα, τα ηλεκτρονικά συστήματα αγορών ή κρατήσεων εισιτηρίων απαιτούν δυναμική αντίληψη των ενημερωμένων πληροφοριών καθώς γίνονται αλλαγές. Σε τέτοιες περιπτώσεις χρησιμοποιείται δυναμικός κέρσορας. Σε αυτές τις εφαρμογές, ο όγκος των δεδομένων που μεταφέρονται είναι συνήθως μικρός και έχει πρόσβαση σε επίπεδο σειράς (ατομική εγγραφή). Η ομαδική πρόσβαση είναι πολύ σπάνια.

Διαχείριση δρομέα σε περιβάλλον MS SQL Server

Έλεγχος δρομέαυλοποιείται εκτελώντας τις ακόλουθες εντολές:

  • ΔΗΛΩΣΤΕ - δημιουργία ή δήλωση δρομέα;
  • ΑΝΟΙΞΕ - άνοιγμα κέρσορα, δηλ. συμπληρώνοντάς το με δεδομένα.
  • ΦΕΡΩ επιλογή από τον κέρσορακαι αλλαγή σειρών δεδομένων χρησιμοποιώντας τον κέρσορα.
  • ΚΛΕΙΣΕ - κλείνοντας τον κέρσορα;
  • ΑΝΑΘΕΣΗ - ελευθερώνοντας τον κέρσορα, δηλ. διαγραφή του δρομέα ως αντικείμενο.

Δήλωση δρομέα

Το πρότυπο SQL παρέχει την ακόλουθη εντολή για τη δημιουργία ενός δρομέα:

Η χρήση της λέξης-κλειδιού ΑΣΑΘΗΣ θα δημιουργήσει στατικό δρομέα. Αλλαγές δεδομένωνδεν επιτρέπονται, επιπλέον δεν εμφανίζονται αλλαγές που έγιναν από άλλους χρήστες. Εάν λείπει η λέξη-κλειδί ΑΝΕΥΑΙΣΘΗΤΟ, α δυναμικός κέρσορας.

Όταν καθορίζετε τη λέξη-κλειδί SCROLL, ο δρομέας που δημιουργήθηκε μπορεί να μετακινηθεί προς οποιαδήποτε κατεύθυνση, επιτρέποντάς σας να χρησιμοποιήσετε οποιεσδήποτε εντολές επιλογής. Εάν αυτό το όρισμα παραλειφθεί, ο δρομέας θα είναι σταθερός, δηλ. η προβολή του θα είναι δυνατή μόνο προς μία κατεύθυνση - από την αρχή μέχρι το τέλος.

Η δήλωση SELECT καθορίζει το σώμα του αιτήματος SELECT, το οποίο καθορίζει το σύνολο γραμμών που προκύπτει για τον κέρσορα.

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

Η δημιουργία ενός δρομέα με ένα όρισμα ΓΙΑ ΕΝΗΜΕΡΩΣΗ σάς επιτρέπει να εκτελέσετε στον κέρσορα αλλαγή δεδομένωνείτε στις καθορισμένες στήλες είτε, ελλείψει του ορίσματος OF στήλη_όνομα, σε όλες τις στήλες.

Στο περιβάλλον του MS SQL Server, η ακόλουθη σύνταξη για την εντολή δημιουργίας δρομέα είναι αποδεκτή:

<создание_курсора>::= ΔΗΛΩΣΗ δρομέα_όνομα ΔΡΟΜΕΤΗ ΓΙΑ SELECT_statement ]]

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

Εάν έχει καθοριστεί η λέξη-κλειδί GLOBAL, δημιουργείται ένας καθολικός δρομέας. υπάρχει μέχρι να κλείσει η τρέχουσα σύνδεση.

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

Ο καθορισμός του SCROLL δημιουργεί με δυνατότητα κύλισης; Τα δεδομένα είναι προσβάσιμα με οποιαδήποτε σειρά και προς οποιαδήποτε κατεύθυνση.

Ο καθορισμός STATIC δημιουργεί στατικό δρομέα.

Ο καθορισμός του KEYSET δημιουργεί έναν δρομέα κλειδιού.

Ο καθορισμός του DYNAMIC δημιουργεί δυναμικός κέρσορας.

Εάν καθορίσετε το όρισμα FAST_FORWARD για έναν δρομέα READ_ONLY, ο δρομέας που δημιουργήθηκε θα βελτιστοποιηθεί για γρήγορη πρόσβαση στα δεδομένα. Αυτό το όρισμα δεν μπορεί να χρησιμοποιηθεί σε συνδυασμό με τα ορίσματα FORWARD_ONLY ή OPTIMISTIC.

Ένας δρομέας που δημιουργήθηκε με το όρισμα OPTIMISTIC εμποδίζει την τροποποίηση ή τη διαγραφή σειρών που τροποποιήθηκαν μετά ανοίγοντας τον κέρσορα.

Καθορίζοντας το όρισμα TYPE_WARNING, ο διακομιστής θα ενημερώσει τον χρήστη για μια σιωπηρή αλλαγή στον τύπο του δρομέα, εάν δεν είναι συμβατή με το ερώτημα SELECT.

Άνοιγμα του κέρσορα

Για ανοίγοντας τον κέρσορακαι συμπληρώνοντάς το με δεδομένα από το ερώτημα SELECT που καθορίστηκε κατά τη δημιουργία του δρομέα, χρησιμοποιήστε την ακόλουθη εντολή:

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

Ανάκτηση δεδομένων από δρομέα

Αμέσως μετά ανοίγοντας τον κέρσοραμπορείτε να επιλέξετε τα περιεχόμενά του (το αποτέλεσμα της εκτέλεσης του αντίστοιχου ερωτήματος) χρησιμοποιώντας την ακόλουθη εντολή:

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

Ο καθορισμός LAST επιστρέφει την πιο πρόσφατη σειρά του δρομέα. Γίνεται και η τρέχουσα γραμμή.

Ο καθορισμός NEXT επιστρέφει τη σειρά αμέσως μετά την τρέχουσα στο πλήρες σύνολο αποτελεσμάτων. Τώρα γίνεται επίκαιρο. Από προεπιλογή, η εντολή FETCH χρησιμοποιεί αυτήν τη μέθοδο για την ανάκτηση σειρών.

Η λέξη-κλειδί PRIOR επιστρέφει τη σειρά πριν από την τρέχουσα. Γίνεται επίκαιρο.

Διαφωνία ΑΠΟΛΥΤΟ (αριθμός_γραμμής | @line_number_variable)επιστρέφει μια γραμμή με τον απόλυτο τακτικό της αριθμό στο πλήρες σύνολο αποτελεσμάτων του δρομέα. Ο αριθμός γραμμής μπορεί να καθοριστεί χρησιμοποιώντας μια σταθερά ή ως όνομα μιας μεταβλητής στην οποία είναι αποθηκευμένος ο αριθμός γραμμής. Η μεταβλητή πρέπει να είναι ακέραιος τύπος δεδομένων. Υποδεικνύονται τόσο οι θετικές όσο και οι αρνητικές τιμές. Κατά τον καθορισμό μιας θετικής τιμής, η συμβολοσειρά μετράται από την αρχή του συνόλου, ενώ μια αρνητική τιμή μετράται από το τέλος. Η επιλεγμένη γραμμή γίνεται η τρέχουσα γραμμή. Εάν οριστεί μηδενική τιμή, δεν επιστρέφεται καμία σειρά.

Διαφωνία ΣΧΕΤΙΚΟ (αριθμός σειρών | @variable αριθμός σειρών)επιστρέφει τη γραμμή που είναι ο καθορισμένος αριθμός γραμμών μετά την τρέχουσα. Εάν καθορίσετε έναν αρνητικό αριθμό σειρών, θα επιστραφεί η σειρά που είναι ο καθορισμένος αριθμός σειρών πριν από την τρέχουσα. Ο καθορισμός μιας μηδενικής τιμής θα επιστρέψει την τρέχουσα σειρά. Η σειρά που επιστρέφεται γίνεται η τρέχουσα σειρά.

Προς την ανοίξτε τον καθολικό δρομέα, πρέπει να καθορίσετε τη λέξη-κλειδί GLOBAL πριν από το όνομά της. Το όνομα του δρομέα μπορεί επίσης να καθοριστεί χρησιμοποιώντας μια μεταβλητή.

Στο σχέδιο INTO @variable_name [,...n]καθορίζεται μια λίστα μεταβλητών στην οποία θα αποθηκευτούν οι αντίστοιχες τιμές στηλών της επιστρεφόμενης σειράς. Η σειρά καθορισμού των μεταβλητών πρέπει να ταιριάζει με τη σειρά των στηλών στον κέρσορα και ο τύπος δεδομένων της μεταβλητής πρέπει να ταιριάζει με τον τύπο δεδομένων στη στήλη του δρομέα. Εάν η κατασκευή INTO δεν έχει καθοριστεί, τότε η συμπεριφορά της εντολής FETCH θα μοιάζει με τη συμπεριφορά της εντολής SELECT - τα δεδομένα εμφανίζονται στην οθόνη.

Αλλαγή και διαγραφή δεδομένων

Για να κάνετε αλλαγές χρησιμοποιώντας έναν δρομέα, πρέπει να εκδώσετε μια εντολή UPDATE στην ακόλουθη μορφή:

Πολλές στήλες της τρέχουσας σειράς του δρομέα μπορούν να αλλάξουν σε μία λειτουργία, αλλά όλες πρέπει να ανήκουν στον ίδιο πίνακα.

Για να διαγράψετε δεδομένα χρησιμοποιώντας δρομέα, χρησιμοποιήστε την εντολή DELETE στην ακόλουθη μορφή:

Ως αποτέλεσμα, το ρεύμα που έχει οριστεί γραμμή στον κέρσορα θα διαγραφεί.

Κλείσιμο του δρομέα

Μετά το κλείσιμο, ο κέρσορας γίνεται απρόσιτος στους χρήστες του προγράμματος. Όταν είναι κλειστό, αφαιρούνται όλες οι κλειδαριές που έχουν εγκατασταθεί κατά τη λειτουργία του. Το κλείσιμο μπορεί να εφαρμοστεί μόνο σε ανοιχτούς δρομείς. Κλειστό αλλά όχι ελευθερωμένος κέρσοραςμπορεί να ξανανοίξει. Δεν επιτρέπεται το κλείσιμο ενός δρομέα που δεν έχει ανοίξει.

Αφήστε τον κέρσορα

Κλείσιμο του δρομέαδεν απελευθερώνει απαραίτητα τη μνήμη που σχετίζεται με αυτό. Ορισμένες υλοποιήσεις πρέπει να το αναθέσουν ρητά χρησιμοποιώντας την πρόταση DEALLOCATE. Μετά απελευθερώστε τον κέρσοραΗ μνήμη ελευθερώνεται επίσης, καθιστώντας δυνατή την επαναχρησιμοποίηση του ονόματος του δρομέα.

Για να ελέγξετε εάν έχει φτάσει το τέλος του δρομέα, συνιστάται να χρησιμοποιήσετε τη συνάρτηση: @@FETCH_STATUS

Η συνάρτηση @@FETCH_STATUS επιστρέφει:

0 εάν η ανάκτηση ήταν επιτυχής.

1 εάν η ανάκτηση απέτυχε λόγω προσπάθειας ανάκτησης μιας γραμμής έξω από τον κέρσορα.

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

DECLARE @id_kl INT, @firm VARCHAR(50), @fam VARCHAR(50), @message VARCHAR(80), @nam VARCHAR(50), @d DATETIME, @p INT, @s INT SET @s=0 PRINT "Λίστα αγορών" ΔΗΛΩΣΤΕ klient_cursor CURSOR LOCAL FOR SELECT Client Code, Company, Last Name FROM Client WHERE City="Moscow" ORDER BY Company, Last Name OPEN klient_cursor FETCH NEXT FROM klient_cursor INTO @id_kl, @STALE, @USFETCH_Fam =0 BEGIN SELECT @message="Πελάτης "+@fam+ "Company "+ @firm PRINT @message SELECT @message="Όνομα προϊόντος Ημερομηνία αγοράς Κόστος" PRINT @message ΔΗΛΩΣΗ tovar_cursor CURSOR FOR SELECT Product.Όνομα, Συναλλαγή.Ημερομηνία, Προϊόν .Τιμή* Συναλλαγή.Ποσότητα ΩΣ Κόστος ΑΠΟ Προϊόν ΕΣΩΤΕΡΙΚΗ ΣΥΝΔΕΣΗ Συναλλαγή ΣΤΟ Προϊόν. Κωδικός προϊόντος=Transaction.Κωδικός προϊόντος WHERE Συναλλαγή.Κωδικός πελάτη=@id_kl OPEN tovar_cursor FETCH NEXT FROM tovar_cursor INTO @nam, @d, @p IF @@FETCH_STATUS<>0 PRINT "No shoppings" WHILE @@FETCH_STATUS=0 BEGIN SELECT @message=" "+@nam+" "+ CAST(@d AS CHAR(12))+" "+ CAST(@p AS CHAR(6)) PRINT @message SET @s=@s+@p FETCH NEXT FROM tovar_cursor INTO @nam, @d, @p END CLOSE tovar_cursor DEALLOCATE tovar_cursor SELECT @message="Συνολικό κόστος "+ CAST(@s AS CHAR(6)) PRINT @message -- μετακίνηση στον επόμενο πελάτη-- FETCH NEXT FROM klient_cursor INTO @id_kl, @firm, @fam END CLOSE klient_cursor DEALLOCATE klient_cursor Παράδειγμα 13.6. Δρομέας για την εμφάνιση μιας λίστας αγαθών που αγοράστηκαν από πελάτες από τη Μόσχα και το συνολικό κόστος τους.

Παράδειγμα 13.7.Αναπτύξτε έναν κυλιόμενο δρομέα για πελάτες από τη Μόσχα. Εάν ο αριθμός τηλεφώνου ξεκινά με 1, διαγράψτε τον πελάτη με αυτόν τον αριθμό και στην πρώτη καταχώρηση δρομέα αντικαταστήστε το πρώτο ψηφίο του αριθμού τηλεφώνου με 4.

ΔΗΛΩΣΤΕ @firm VARCHAR(50), @fam VARCHAR(50), @tel VARCHAR(8), @message VARCHAR(80) ΕΚΤΥΠΩΣΗ "Λίστα πελατών" ΔΗΛΩΣΤΕ klient_cursor CURSOR GLOBAL SCROLL KEYSET FOR SELECT Firm, Last name, Phone FROM WHERE City ="Moscow" ΠΑΡΑΓΓΕΛΙΑ ΑΠΟ Εταιρεία, Επώνυμο ΓΙΑ ΕΝΗΜΕΡΩΣΗ OPEN klient_cursor FETCH NEXT FROM klient_cursor INTO @firm, @fam, @tel WHILE @@FETCH_STATUS=0 BEGIN SELECT @message="Client "+@fam+ " Company "+ @firm " Τηλέφωνο "+ @tel PRINT @message -- εάν ο αριθμός τηλεφώνου ξεκινά με 1, -- διαγράψτε τον πελάτη με αυτόν τον αριθμό ΑΝ @tel LIKE '1%' DELETE Client WHERE CURRENT OF klient_cursor ALSE -- μεταβείτε στο επόμενο client FETCH NEXT FROM klient_cursor INTO @firm, @fam, @tel END FETCH ABSOLUTE 1 FROM klient_cursor INTO @firm, @fam, @tel -- στην πρώτη καταχώριση, αντικαταστήστε το πρώτο ψηφίο στον αριθμό τηλεφώνου με 4 ΕΝΗΜΕΡΩΣΗ ΣΕΤ πελάτη ='4' + RIGHT(@ tel,LEN(@tel)-1)) WHERE CURRENT OF klient_cursor SELECT @message="Client "+@fam+" Firm "+ @firm "Phone "+ @tel PRINT @message CLOSE klient_cursor DEALLOCATE klient_cursor Παράδειγμα 13.7. Με δυνατότητα κύλισης για πελάτες από τη Μόσχα.

Παράδειγμα 13.8.Χρήση δρομέα ως παράμετρος εξόδου της διαδικασίας. Η διαδικασία επιστρέφει ένα σύνολο δεδομένων - μια λίστα προϊόντων.

Η κλήση της διαδικασίας και η εκτύπωση δεδομένων από τον κέρσορα εξόδου εκτελούνται ως εξής:

ΔΗΛΩΣΤΕ @my_cur CURSOR ΔΗΛΩΣΤΕ @n VARCHAR(20) EXEC my_proc @cur=@my_cur ΑΝΑΓΚΗ ΕΞΟΔΟΥ ΕΠΟΜΕΝΟ ΑΠΟ @my_cur ΣΕ @n ΕΠΙΛΟΓΗ @n ΕΝΩ (@@FETCH_STATUS=0) ΑΡΧΙΣΤΕ ΛΗΨΗ ΕΠΟΜΕΝΟ ΑΠΟ @_n ΤΕΛΟΣ ΚΛΕΙΣΙΜΟ @my_cur ΑΝΑΘΕΣΗ @my_cur

Δρομέαςσε SQL, μια περιοχή στη μνήμη της βάσης δεδομένων που είναι αφιερωμένη στην αποθήκευση της τελευταίας πρότασης SQL. Εάν η τρέχουσα δήλωση είναι ένα ερώτημα βάσης δεδομένων, μια συμβολοσειρά δεδομένων ερωτήματος που ονομάζεται τρέχουσα τιμή ή τρέχουσα σειρά, αποθηκεύεται επίσης στη μνήμη. δρομέας. Η καθορισμένη περιοχή στη μνήμη ονομάζεται και είναι προσβάσιμη σε προγράμματα εφαρμογών.

Σύμφωνα με το πρότυπο SQL κατά την εργασία με δρομείςμπορούν να εντοπιστούν τα ακόλουθα κύρια Ενέργειες:

  • δημιουργία ή δήλωση δρομέα ;
  • ανοίγοντας τον κέρσορα, εκείνοι. γεμίζοντάς το με δεδομένα που είναι αποθηκευμένα σε μνήμη πολλαπλών επιπέδων.
  • επιλογή από τον κέρσοραΚαι αλλαγήχρησιμοποιώντας το γραμμές δεδομένων?
  • κλείνοντας τον κέρσορα, μετά το οποίο γίνεται απρόσιτο για τα προγράμματα των χρηστών.
  • ελευθερώνοντας τον κέρσορα, δηλ. διαγραφή δρομέαςως αντικείμενο, γιατί αυτό κλείσιμοδεν απελευθερώνει απαραίτητα τη μνήμη που σχετίζεται με αυτό.

Ο SQL Server υποστηρίζει τρία τύπος δρομέων:

  • δρομείςΗ SQL χρησιμοποιείται κυρίως σε ενεργοποιητές, αποθηκευμένες διαδικασίες και σενάρια.
  • δρομείςοι διακομιστές ενεργούν στον διακομιστή και υλοποιούν τη διεπαφή προγραμματισμού εφαρμογών για ODBC, OLE DB, DB_Library.
  • δρομείςπελάτης υλοποιούνται στον ίδιο τον πελάτη. Λαμβάνουν ολόκληρο το σύνολο αποτελεσμάτων των σειρών από τον διακομιστή και το αποθηκεύουν τοπικά, γεγονός που επιταχύνει την επεξεργασία δεδομένων μειώνοντας τον χαμένο χρόνο που δαπανάται σε λειτουργίες δικτύου.

Διαχείριση δρομέα σε περιβάλλον MS SQL Server

Έλεγχος δρομέαυλοποιείται εκτελώντας τις ακόλουθες εντολές:

  • ΔΗΛΩΣΤΕ - δημιουργία ή δήλωση δρομέα ;
  • ΑΝΟΙΞΕ - άνοιγμα κέρσορα, δηλ. συμπληρώνοντάς το με δεδομένα.
  • ΦΕΡΩ επιλογή από τον κέρσοραΚαι αλλαγήσειρές δεδομένων με χρήση δρομέα.
  • ΚΛΕΙΣΕ - κλείνοντας τον κέρσορα ;
  • ΑΝΑΘΕΣΗ – ελευθερώνοντας τον κέρσορα, δηλ. διαγραφή του δρομέα ως αντικείμενο.

Δήλωση δρομέα

Στο πρότυπο SQL για τη δημιουργία δρομέαςΠαρέχεται η ακόλουθη εντολή:

<создание_курсора>::= ΔΗΛΩΣΗ δρομέα_όνομα ΔΡΟΜΕΑ ΓΙΑ SELECT_statement ])]

Η χρήση της λέξης-κλειδιού ΑΣΑΘΗΣ θα δημιουργήσει στατικό δρομέα. Αλλαγές δεδομένωνδεν επιτρέπονται, επιπλέον, δεν εμφανίζονται αλλαγές, κατασκευασμένο από άλλους χρήστες. Εάν λείπει η λέξη-κλειδί ΑΝΕΥΑΙΣΘΗΤΟ, α δυναμικός κέρσορας.



Όταν καθορίζετε τη λέξη-κλειδί SCROLL, δημιουργείται δρομέαςμπορεί να μετακινηθεί προς οποιαδήποτε κατεύθυνση, επιτρέποντάς σας να εφαρμόσετε οποιεσδήποτε εντολές δείγματα. Εάν αυτό το όρισμα παραλειφθεί, τότε δρομέαςαποδεικνύεται σταθερός, δηλ. η προβολή του θα είναι δυνατή μόνο προς μία κατεύθυνση - από την αρχή μέχρι το τέλος.

Η δήλωση SELECT καθορίζει το σώμα του ερωτήματος SELECT, το οποίο καθορίζει το σύνολο αποτελεσμάτων των σειρών δρομέας.

Ο καθορισμός του ορίσματος ΓΙΑ READ_ONLY δημιουργείται δρομέας"μόνο για ανάγνωση" και δεν επιτρέπεται καμία τροποποίηση των δεδομένων. Είναι διαφορετικό από στατικός, αν και το τελευταίο δεν σας επιτρέπει επίσης να αλλάξετε δεδομένα. Μπορεί να δηλωθεί ως δρομέας μόνο για ανάγνωση δυναμικός κέρσορας, το οποίο θα σας επιτρέψει να εμφανίσετε αλλαγές, κατασκευασμένο από άλλο χρήστη.

Δημιουργία δρομέαςμε το όρισμα ΓΙΑ ΕΝΗΜΕΡΩΣΗ σας επιτρέπει να εκτελέσετε μέσα αλλαγή δεδομένων δρομέαείτε στις καθορισμένες στήλες είτε, ελλείψει του ορίσματος OF στήλη_όνομα, σε όλες τις στήλες.

Στο περιβάλλον MS SQL Server, η ακόλουθη σύνταξη για την εντολή δημιουργίας είναι αποδεκτή δρομέας:

<создание_курсора>::= ΔΗΛΩΣΗ δρομέα_όνομα ΔΡΟΜΕΤΗ ΓΙΑ SELECT_statement ]]

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

Εάν έχει καθοριστεί η λέξη-κλειδί GLOBAL, μια καθολική δρομέας; υπάρχει μέχρι να κλείσει η τρέχουσα σύνδεση.

Ο καθορισμός FORWARD_ONLY δημιουργεί σειριακό δρομέα ; δείγμαΤα δεδομένα μπορούν να υποβληθούν σε επεξεργασία μόνο προς την κατεύθυνση από την πρώτη γραμμή προς την τελευταία.

Ο καθορισμός του SCROLL δημιουργεί με δυνατότητα κύλισης; Τα δεδομένα είναι προσβάσιμα με οποιαδήποτε σειρά και προς οποιαδήποτε κατεύθυνση.

Ο καθορισμός STATIC δημιουργεί στατικό δρομέα.

Ο καθορισμός του KEYSET δημιουργεί έναν δρομέα κλειδιού.

Ο καθορισμός του DYNAMIC δημιουργεί δυναμικός κέρσορας.

Αν για δρομέας READ_ONLY καθορίστε το όρισμα FAST_FORWARD και στη συνέχεια δημιουργήθηκε δρομέαςθα βελτιστοποιηθεί για γρήγορη πρόσβαση στα δεδομένα. Αυτό το όρισμα δεν μπορεί να χρησιμοποιηθεί σε συνδυασμό με τα ορίσματα FORWARD_ONLY ή OPTIMISTIC.

ΣΕ δρομέας, που δημιουργήθηκε με το όρισμα ΑΙΣΙΟΔΟΞΟΣ, απαγορεύεται αλλαγήΚαι διαγραφή σειρώνπου άλλαξαν μετά ανοίγοντας τον κέρσορα.

Κατά τον καθορισμό του ορίσματος TYPE_WARNING, ο διακομιστής θα ενημερώσει τον χρήστη για την σιωπηρή αλλαγή τύπου δρομέαςεάν δεν είναι συμβατό με το ερώτημα SELECT.

Άνοιγμα του κέρσορα

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

OPEN ((cursor_name) |@cursor_variable_name)

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

Ανάκτηση δεδομένων από δρομέα

Αμέσως μετά ανοίγοντας τον κέρσοραμπορείτε να επιλέξετε τα περιεχόμενά του (το αποτέλεσμα της εκτέλεσης του αντίστοιχου ερωτήματος) χρησιμοποιώντας την ακόλουθη εντολή:

ΑΝΑΓΚΗ [ ΑΠΟ ]((όνομα_δρομέα)| @cursor_variable_name) ]

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

Ο καθορισμός LAST επιστρέφει την πιο πρόσφατη σειρά δρομέας. Γίνεται και η τρέχουσα γραμμή.

Ο καθορισμός NEXT επιστρέφει τη σειρά αμέσως μετά την τρέχουσα στο πλήρες σύνολο αποτελεσμάτων. Τώρα γίνεται επίκαιρο. Από προεπιλογή, η εντολή FETCH χρησιμοποιεί αυτήν τη μέθοδο. δείγματαγραμμές.

Η λέξη-κλειδί PRIOR επιστρέφει τη σειρά πριν από την τρέχουσα. Γίνεται επίκαιρο.

ABSOLUTE (row_number | @row_number_variable) επιστρέφει τη σειρά με τον απόλυτο αριθμό ευρετηρίου της στο πλήρες σύνολο αποτελεσμάτων δρομέας. Ο αριθμός γραμμής μπορεί να καθοριστεί χρησιμοποιώντας μια σταθερά ή ως όνομα μιας μεταβλητής στην οποία είναι αποθηκευμένος ο αριθμός γραμμής. Η μεταβλητή πρέπει να είναι ακέραιος τύπος δεδομένων. Υποδεικνύονται τόσο οι θετικές όσο και οι αρνητικές τιμές. Κατά τον καθορισμό μιας θετικής τιμής, η συμβολοσειρά μετράται από την αρχή του συνόλου, ενώ μια αρνητική τιμή μετράται από το τέλος. Η επιλεγμένη γραμμή γίνεται η τρέχουσα γραμμή. Εάν οριστεί μηδενική τιμή, δεν επιστρέφεται καμία σειρά.

Το όρισμα RELATIVE (αριθμός σειρών | @variable αριθμός σειρών) επιστρέφει τη σειρά που είναι ο καθορισμένος αριθμός σειρών μετά την τρέχουσα. Εάν καθορίσετε έναν αρνητικό αριθμό σειρών, θα επιστραφεί η σειρά που είναι ο καθορισμένος αριθμός σειρών πριν από την τρέχουσα. Ο καθορισμός μιας μηδενικής τιμής θα επιστρέψει την τρέχουσα σειρά. Η σειρά που επιστρέφεται γίνεται η τρέχουσα σειρά.

Προς την ανοίξτε τον καθολικό δρομέα, πρέπει να καθορίσετε τη λέξη-κλειδί GLOBAL πριν από το όνομά της. Ονομα δρομέαςμπορεί επίσης να καθοριστεί χρησιμοποιώντας μια μεταβλητή.

Η κατασκευή INTO @variable_name [,...n] καθορίζει μια λίστα μεταβλητών στην οποία θα αποθηκευτούν οι αντίστοιχες τιμές στήλης της συμβολοσειράς που επιστρέφεται. Η σειρά των μεταβλητών πρέπει να ταιριάζει με τη σειρά των στηλών μέσα δρομέας, και ο τύπος δεδομένων της μεταβλητής είναι ο τύπος δεδομένων στη στήλη δρομέας. Εάν η κατασκευή INTO δεν έχει καθοριστεί, τότε η συμπεριφορά της εντολής FETCH θα μοιάζει με τη συμπεριφορά της εντολής SELECT - τα δεδομένα εμφανίζονται στην οθόνη.

Συνεχίζοντας το θέμα:
Δίκτυα

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

Νέα άρθρα
/
Δημοφιλής