Cursors?

Τί εννοείς διαφορετική υλοποίηση? Ακόμα και στην Oracle οι cursors δεν διαφέρουν ουσιαστικά.
Όσον αφορά την παράμετρο πίνακα, αυτό έρχεται σε αντίθεση με την ίδια την έννοια του stored procedure. Δεν είναι θέμα του SQL Server αλλά οποιασδήποτε βάσης. Ένα stored procedure
μοιάζει με ένα τυπικό procedure, καθώς μπορεί να γράψει κανείς κώδικα. Όταν όμως γίνεται compile το stored procedure αποθηκεύεται και το execution plan των query που περιέχει το stored procedure. Η μορφή του execution plan εξαρτάται από τους πίνακες που χρησιμοποιεί το query, τα indexes που έχουν οριστεί αλλά και τις τιμές που περιέχουν τα indexes. Η χρησιμότητα του stored procedure είναι ότι το execution plan υπάρχει έτοιμο και έτσι δεν χρειάζεται να υπολογίζεται κάθε φορά που καλείται το stored procedure. Το κέρδος για ένα stored procedure που εκτελείται συχνά είναι πολύ σημαντικό.
Αν τώρα μπορούσες να περάσεις ένα πίνακα σαν παράμετρο, ποιό execution plan θα χρησιμοποιούσε το stored procedure? Το αποθηκευμένο μάλλον δεν ταιριάζει. Αν ξανακάνει compile, χάνεται το πλεονέκτημα της ταχύτητας.
Άλλο πρόβλημα είναι τα permissions των πινάκων. Το stored procedure μπορεί να φτιάχτηκε έχοντας permissions να διαβάσει τον Χ πίνακα. Αν του περάσεις τον Υ, τί θα πρέπει να κάνει? Αν ξανακάνει έλεγχο permissions, χάνεται πάλι το όφελος σε ταχύτητα.
Το πρόβλημα αυτό δεν είναι μόνο του SQL Server. Απλά, τα stored procedures δεν είναι φτιαγμένα για να δουλεύουν σαν functions. Αν θέλεις να χρησιμοποιήσεις ένα παρόμοιο query σε διαφορετικούς πίνακες, καλύτερα να χρησιμοποιήσεις ένα code generator.
Ανέφερες ότι μπορείς να περάσεις ένα cursor σαν παράμετρο. Το cursor δεν έχει καμμία σχέση με τους πίνακες. Θα πρέπει να το δεις σαν ένα recordset το οποίο είσαι αναγκασμένος να διαβάσεις γραμμή-γραμμή. Σκέψου το σαν να είχε επιλέξει ο query optimizer ένα πολύ αργό table scan με έξτρα καθυστερήσεις. Όταν λοιπόν περνάς ένα cursor είναι σα να περνάς ένα recordset. Το stored procedure περιμένει να διαβάσει κάποια πεδία ένα-ένα και δεν το ενδιαφέρει αν υπάρχουν περισσότερα από όσα περιμένει. Σημειωτέον, στην Oracle όπου τα cursors έχουν τύπο, δεν μπορείς να περάσεις ένα cursor που έχει διαφορετικά πεδία από αυτά που περιμένει το stored procedure. Από την έκδοση 9 και μετά βέβαια υπάρχει και ένας γενικός cursor.
Γενικά οι cursors θεωρούνται "η ρίζα του κακού" για τα περισσότερα προβλήματα ταχύτητας στις databases. Να προτείνω δύο πολύ καλά βιβλία του
Joe Celko, όπου περιγράφει πως να χρησιμοποιήσει κανείς SQL εκεί που νόμιζε ότι η μόνη λύση ήταν τα cursors:
SQL For Smarties και το
SQL Puzzles and Answers, and you will never write another cursor again!
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos