Is it possible to Join a table with a stored procedure?
Thursday 25 September 2014
Σε όλους είναι γνωστό ότι δεν μπορείς ένα table να τον κάνεις join με μια stored procedure η οποία γυρνάει αποτελέσματα σε μορφή table. Είναι όντως 100% αλήθεια και αν δεν είναι γιατί δεν το χρησιμοποιούμε;
Πραγματικά κάτι τέτοιο συντακτικά είναι αδύνατον να γίνει, τουλάχιστον με την γνωστή σύνταξη του join, άρα ναι δεν μπορείς να το κάνεις.
Δηλαδή μια τέτοια σύνταξη δεν υπάρχει
SELECT COL1,COL2, FROM T1 INNER JOIN SP_NAME ON ….
Όμως μπορείς να φτιάξεις ένα προσωρινό πίνακα (#table ) ή table variable που θα έχει σαν δομή την γραμμογράφηση των αποτελεσμάτων που η stored procedure επιστρέφει.
Αυτό όπως είναι κατανοητό προϋποθέτει ότι πρέπει να φτιάξεις πρώτα το #table ή το table variable και μετά με INSERT EXEC να γεμίσεις αυτόν και μετά να κάνεις το join που θέλεις.
Μια τεχνική που δουλεύει αρκετά καλά όταν δεν έχω μεγάλο όγκο δεδομένων αλλά έχει και μειονεκτήματα όπως για παράδειγμα αν αλλάξει η stored procedure θα πρέπει να αλλάξει και η δομή του #table.
Αν πάλι η υλοποίηση της stored procedure είναι ένα μόνο ένα select που έχει where clause που απλά παίρνει τιμές από τις παραμέτρους αυτό είναι εύκολο να γίνει ένα user defined function και με τον APPLY operator να κάνω join. Βέβαια η βασική προϋπόθεση είναι ότι μπορώ να φτιάξω αυτή την UDF.
Αν όμως έχεις μια stored procedure που έχει ένα περίπλοκο implementation και μια επιχειρηματική λογική που δύσκολα αλλάζει ή δεν έχεις τον χρόνο να την αλλάξεις και θέλεις να μπορέσεις να παντρέψεις τα δεδομένα της με έναν ή περισσότερους πίνακες, φυσικά με την προϋπόθεση ότι υπάρχει το πεδίο που θα λειτουργήσει σαν foreign key, και ο όγκος των δεδομένων δεν είναι υπερβολικά μεγάλος τοτε με το παρακάτω tip μπορείς να κάνεις το join που θέλεις. Αυτό γίνεται με το να εκμεταλλευτώ την OPENROWSET εντολή που υπάρχει στον SQL Server.
Στο παράδειγμα που παραθέτω χρησιμοποιώ την Northwind database και κάνω χρήση μιας stored procedure που ήδη υπάρχει σε αυτή.
select * from orders as o
inner join (SELECT * FROM OPENROWSET ('SQLOLEDB','Server=(local);TRUSTED_CONNECTION=YES;database=northwind;',
'exec [dbo].[Employee Sales by Country] ''19900101'',''20141231''') ) as sp on sp.orderid=o.OrderID
Enjoy it
/*antonch*/
Υ.Γ
Πέρασαν αρκετές μέρες από το τελευταίο μου post αλλά ο μήνας αυτός προέκυψε αρκετά δραστήριος τόσο με μαθήματα αλλά και τρία SQL Server Health checks και performance tuning. Παράλληλα υπήρχαν και υπάρχουν οι προετοιμασίες για το 1o SQL Saturday του PASS στην Ελλάδα, αλλά και οι προετοιμασίες για το επόμενο IT PRO DEV CONNECTIONS 2014. Σε όλα αυτά υπάρχει και το autoexec.gr που πρέπει να βγει και πάλι στον αέρα το οποίο φαίνεται να τελειώνει.