2012-09-26 19 views
7

SQL सर्वर के लिए सीएलआर उपयोगकर्ता-परिभाषित फ़ंक्शन बनाने का कोई तरीका है जो तालिका मूल्यवान फ़ंक्शन सिंटैक्स का उपयोग किए बिना एकाधिक मान देता है? उदाहरण के लिए, कहें कि मैं एक समन्वय रूपांतरण करना चाहता हूं जैसे:आउट पैरामीटर के साथ एसक्यूएल सर्वर सीएलआर यूडीएफ - क्या यह संभव है?

[SqlFunction()] 
public void ConvertCoordinates(SqlDouble x, SqlDouble y, SqlDouble z, out SqlDouble r, out SqlDouble t, out SqlDouble p) 
{ 
    r = new SqlDouble(Math.Sqrt((x.Value*x.Value)+(y.Value*y.Value)+(z.Value*z.Value))); 
    t = new SqlDouble(Math.Acos(r.Value/z.Value)); 
    p = new SqlDouble(Math.Atan(y.Value/x.Value)); 
} 

क्या यह भी संभव है? इस मामले में एक तालिका-मूल्यवान फ़ंक्शन अनुचित लगता है क्योंकि गणना कभी भी एक से अधिक आउटपुट पंक्ति उत्पन्न नहीं करेगी। स्केलर मूल्यवान फ़ंक्शन सिंटैक्स का उपयोग करके, मुझे गणना करने के लिए तीन अलग-अलग फ़ंक्शन लिखना होगा और प्रत्येक को अलग से कॉल करना होगा। मेरे वास्तविक उपयोग मामले को देखते हुए, यह बेहद अव्यवहारिक है।

मुझे एहसास है कि उपर्युक्त तर्क शुद्ध टी-एसक्यूएल का उपयोग करके पूरा किया जा सकता है; मेरा वास्तविक उपयोग केस अधिक जटिल है लेकिन फिर भी केवल एक पंक्ति में परिणाम होगा जिसमें कई परस्पर निर्भर आउटपुट मान होंगे।

तो, नीचे की रेखा, क्या यह व्यवहार्य है? मुझे नहीं लगता कि यह है, लेकिन कोई उम्मीद कर सकता है। यदि मौके से यह व्यवहार्य है, तो टी-एसक्यूएल कैसा दिखता है जो इस तरह के एक समारोह को कॉल करता है?

+1

यूडीएफ (चाहे स्केलर, या टैबुलर, टी-एसक्यूएल या सीएलआर) पैरामीटर नहीं हो सकते हैं। यदि वे कर सकते हैं, तो आप इन आउटपुट का उपभोग करना चाहते हैं, तो आपको 'SELECT' खंड में कॉल करने की अनुमति देने के लिए नया वाक्यविन्यास आविष्कार करना होगा। और मुझे नहीं लगता कि एक पंक्ति-मूल्यवान फ़ंक्शन एक पंक्ति को लौटने के लिए क्यों अजीब लग रहा है। –

+1

@ डेमियन यह सिर्फ एक प्रश्न था कि यह संभव है या नहीं।मेरे स्वयं के पढ़ने और प्रयोग ने संकेत दिया था कि शायद यह नहीं था (जैसा कि मैंने भी कहा था), लेकिन चूंकि मैं सीएलआर एकीकरण के लिए नया हूं, मैं पूछना चाहता था। जब 1 से अधिक पंक्ति एक संभावना है तो टीवीएफ "मेरे लिए अजीब" प्रतीत नहीं होता है। उदाहरण हमेशा एक पंक्ति देता है, फिर भी अंतःसंबंधित वापसी मान केवल सेट के रूप में सार्थक होते हैं। मेरे वास्तविक उपयोग मामले में मैं लाखों पंक्तियों के लिए एक समान, लेकिन बड़ी गणना कर रहा हूं, इसलिए आउटपुट पैरामीटर एक संभावना होने पर एक टीवीएफ बस अक्षम होता है। एक सरल 'नहीं' पर्याप्त होता। – bporter

+0

@ बोर्टर - जाहिर है कि एक टीवीएफ सबसे अच्छा विकल्प होगा - आप इसे स्वयं कहते हैं, वे "अजीब लगते हैं जब 1 से अधिक पंक्ति एक संभावना है" और फिर कहें कि आपके पास लाखों पंक्तियां हैं। एर्गो ए (एस) टीवीएफ जवाब है! यह एक अनिवार्य foreach स्टेटमेंट की तरह हर पंक्ति पर फिर से शुरू करने से अधिक कुशल होने जा रहा है। – gbjbaanb

उत्तर

3

के बाद से आप पहले से ही CLR डुबकी लिया है, आप अपने खुद CLR प्रकार बना सकते हैं जो आप कर सकते हैं के साथ पागल सामान के सभी प्रकार करो। व्यावहारिक उदाहरण के रूप में, मूल स्थानिक प्रकार इस तरह कार्यान्वित किए जाते हैं, जैसा कि पदानुक्रमित है। एक बार जब आप अपना खुद का प्रकार परिभाषित कर लेंगे, तो आप अपना फ़ंक्शन इसे वापस कर सकते हैं। यदि व्यक्तिगत घटकों पर हो रहा है (यदि मैं आपके मामले त्रिज्या, थेटा, और फाई में अनुमान लगा सकता हूं), इस तरह के प्रकार पर विधियां बनाएं।

+0

सुझाव के लिए धन्यवाद। यूडीटी इसे इतना आसान बना देगा, और मैंने उन्हें देखा था। मेरी एकमात्र चिंता यह थी कि मुझे प्रत्येक डेटाबेस के साथ असेंबली पंजीकृत करना है। मेरे मामले में, मैं पिछले 10 वर्षों में जमा किए गए सैकड़ों डेटाबेस से डेटा खनन कर रहा हूं। यूडीएफ आसान लग रहा था क्योंकि मैं उन्हें एक डेटाबेस में रख सकता था और उन्हें कंप्यूटेशंस करने के लिए अन्य डेटाबेस से कॉल कर सकता था। क्या कोई तरीका है कि आप यूडीटी को स्थानिक प्रकारों (प्रत्येक डेटाबेस के साथ असेंबली पंजीकृत किए बिना) के सभी डेटाबेस में उपलब्ध कराने के बारे में जानते हैं? – bporter

+0

मैं कुछ दृष्टिकोणों के बारे में सोच सकता हूं। पहला यह है कि यदि आप इसे एक बार डीबी में पंजीकृत करते हैं और उस डीबी के संदर्भ में अपने सभी डेटा संग्रह करते हैं। दूसरा इसे हर जगह तैनात करना होगा। चूंकि यह टी-एसक्यूएल है और संभवतः आपके पास प्रत्येक डीबी के खिलाफ कोड चलाने का एक तरीका है, यह कोई मुद्दा नहीं होना चाहिए। ध्यान रखें कि आप डीएलएल को हर जगह तैनात करने और संदर्भित करने के बजाय स्क्रिप्ट में बिटस्ट्रीम अधिकार के माध्यम से असेंबली को तैनात कर सकते हैं। –

-1

मैं मानता हूं कि मैं यह प्रयास नहीं किया है, लेकिन मुझे लगता है T-SQL चाहते हैं,

DECLARE @X FLOAT(53), 
     @Y FLOAT(53), 
     @Z FLOAT(53), 
     @R FLOAT(53), 
     @T FLOAT(53), 
     @P FLOAT(53) 

EXEC ConvertCoordinates 
     @X = 0, 
     @Y = 0, 
     @Z = 0, 
     @R = @R OUTPUT, 
     @T = @T OUTPUT 
     @P = @P OUTPUT 
1

यह एक पुराना सवाल है और मैंने इसे एक बहुत ही समान प्रश्न के उत्तर की खोज करते समय पाया।

एसक्यूएल फ़ंक्शंस रिटर्न वैल्यू के लिए अनुमति देते हैं लेकिन आउटपुट पैरामीटर के उपयोग की अनुमति नहीं देते हैं।

एसक्यूएल प्रक्रिया की अनुमति नहीं उत्पादन मानकों (लेकिन नहीं एक वापसी मान)

मैं यहाँ MSDN उदाहरण से इस पाया:

http://technet.microsoft.com/en-us/library/ms131092.aspx

[Microsoft.SqlServer.Server.SqlProcedure] 
public static void PriceSum(out SqlInt32 value) 
{ … } 

और

CREATE PROCEDURE PriceSum (@sum int OUTPUT) 
AS EXTERNAL NAME TestStoredProc.StoredProcedures.PriceSum 

जब मैंने एक प्रक्रिया में एक फ़ंक्शन पंजीकृत करने का प्रयास करने से स्विच किया सब कुछ काम किया। यह ध्यान दिया जाना चाहिए कि एक समारोह में वापसी मूल्य हो सकता है लेकिन एक संग्रहीत प्रक्रिया नहीं कर सकती है। मेरे मामले में मैं एक स्ट्रिंग वैल्यू लौटा रहा था और कुछ वैकल्पिक विस्तृत जानकारी जैसे स्टेटस कोड इत्यादि के लिए आउटपुट पैराम्स था। मैंने जो कुछ किया वह मेरी विधि को शून्य के रूप में बदल गया था और स्ट्रिंग वैल्यू को आउटपुट पैरा के रूप में वापस पास कर दिया था।

आपकी विधि किसी भी तरह की शून्य है और उसके पास कोई वापसी मूल्य नहीं है और यह एक कार्य के बजाय संग्रहीत प्रक्रिया का उपयोग करने के लिए एक आदर्श उम्मीदवार है।