क्यों स्केलर मूल्यवान कार्यों का चयन करने के बजाय अनुमति निष्पादित करने की आवश्यकता है?


15

मैं सोच रहा हूँ कि, स्केलर वैल्यू फंक्शन के लिए, कि मुझे यूजर को सिर्फ एक सेलेक्ट करने के बजाए एक्सेप्ट करना है?

इस बीच एक टेबल वैल्यू फ़ंक्शन केवल चुनिंदा अनुमति या db_datareaderसदस्यता के साथ ठीक काम करता है ।

यहाँ और अधिक स्पष्ट होना मेरा उदाहरण है: मुझे एक ऐसे उपयोगकर्ता की आवश्यकता है जिसने केवल डेटाबेस के लिए अनुमति पढ़ी हो। इसलिए मैंने एक उपयोगकर्ता को बुलाया testUserऔर इसे db_datareaderसदस्यता प्रदान की। तब मैंने एक टेबल वैल्यू फंक्शन बनाया, जिसे बुलाया गया fn_InlineTable। और सब महान है। testUserपूरे दिन इस SQL ​​को चलाता है

select * from dbo.fn_InlineTable

तब मुझे स्केलर फ़ंक्शन की आवश्यकता होती है, इसलिए मैंने एक स्केलर फ़ंक्शन बनाया, जिसे कहा जाता है fn_ScalarTesttestUserइस SQL ​​को नहीं चला सकते

Select dbo.fn_ScalarTest(1) 

अच्छी तरह से समझ में आता है: ऐसा इसलिए है क्योंकि मैंने "परीक्षक" को निष्पादित करने की अनुमति नहीं दी है fn_ScalarTest

मेरा प्रश्न है: इस लिंक पर आधारित /programming/6150888/insert-update-delete-with-function-in-sql-server , का कहना है FUNCTIONकि डेटाबेस स्थिति को संशोधित करने के लिए उपयोग नहीं किया जा सकता है । तो क्यों नहीं एक स्केलर फ़ंक्शन को निष्पादन की अनुमति के बजाय उसी "SELECT" अनुमति के साथ उपयोग किया जाए ??

मुझे उम्मीद है कि मेरा सवाल समझ में आता है। धन्यवाद।

जवाबों:


15

सबसे अधिक संभावना यह है कि टेबल-वैल्यूड फंक्शंस टेबल और व्यूज की तरह ही रिजल्ट सेट लौटाते हैं। इसका मतलब है कि वे में इस्तेमाल किया जा सकता FROMखंड (सहित JOINऔर APPLYके एस, आदि) SELECT, UPDATEऔर DELETEप्रश्नों। हालाँकि, आप उनमें से किसी भी संदर्भ में एक स्केलर यूडीएफ का उपयोग नहीं कर सकते हैं।

दूसरे, आप EXECUTEएक स्केलर यूडीएफ भी कर सकते हैं । जब आप इनपुट मापदंडों के लिए डिफ़ॉल्ट मान निर्दिष्ट करते हैं तो यह सिंटैक्स काफी उपयोगी होता है। उदाहरण के लिए, निम्न यूडीएफ लें:

CREATE FUNCTION dbo.OptionalParameterTest (@Param1 INT = 1, @Param2 INT = 2)
RETURNS INT
AS
BEGIN
    RETURN @Param1 + @Param2;
END;

यदि आप किसी भी इनपुट पैरामीटर को "वैकल्पिक" के रूप में मानना ​​चाहते हैं, तो आपको तब भी DEFAULTकीवर्ड में पास करना होगा जब हस्ताक्षर तय होने के बाद से इसे एक फ़ंक्शन की तरह कॉल किया जा सके:

DECLARE @Bob1 INT;

SET @Bob1 = dbo.OptionalParameterTest(100, DEFAULT);

SELECT @Bob1;
-- Returns: 102

दूसरी ओर, यदि आप EXECUTEकार्य करते हैं, तो आप किसी भी मानदंड को डिफ़ॉल्ट रूप से सही मायने में वैकल्पिक मान सकते हैं, ठीक वैसे ही जैसे आप संग्रहीत कार्यविधियों के साथ कर सकते हैं। आप पैरामीटर नामों को निर्दिष्ट किए बिना पहले n मापदंडों में पास कर सकते हैं :

DECLARE @Bob2 INT;

EXEC @Bob2 = dbo.OptionalParameterTest 50;

SELECT @Bob2;
-- Returns: 52

आप पैरामीटर नामों को निर्दिष्ट करके पहले पैरामीटर को भी छोड़ सकते हैं, फिर से, जैसे कि संग्रहीत कार्यविधियाँ:

DECLARE @Bob3 INT;

EXEC @Bob3 = dbo.OptionalParameterTest @Param2 = 50;

SELECT @Bob3;
-- Returns: 51

अपडेट करें

आप EXECकेवल एक संग्रहीत प्रक्रिया की तरह स्केलर यूडीएफ को कॉल करने के लिए वाक्यविन्यास का उपयोग क्यों करना चाहते हैं ? कभी-कभी यूडीएफ होते हैं जो यूडीएफ के रूप में महान होते हैं क्योंकि उन्हें एक क्वेरी में जोड़ा जा सकता है और लौटे पंक्तियों के सेट पर काम कर सकता है, जबकि यदि कोड एक संग्रहीत प्रक्रिया में थे, तो इसे एक कर्सर में रखने की आवश्यकता होगी। पंक्तियों के एक सेट पर पुनरावृति। लेकिन फिर ऐसे समय होते हैं कि आप उस फ़ंक्शन को एक एकल मूल्य पर कॉल करना चाहते हैं, संभवतः दूसरे यूडीएफ के भीतर से। एकल मान के लिए UDF को कॉल करना या तो किया जा सकता है:

SELECT dbo.UDF('some value');

जिस स्थिति में आपको परिणाम सेट में रिटर्न वैल्यू मिलती है (परिणाम सेट काम नहीं करेगा)। या यह निम्नानुसार किया जा सकता है:

DECLARE @Dummy INT;

SET @Dummy = dbo.UDF('some value');

किस मामले में आपको @Dummyचर घोषित करने की आवश्यकता है ;

कैसे, EXECवाक्यविन्यास के साथ , आप उन दोनों परेशानियों से बच सकते हैं:

EXEC dbo.UDF 'some value';

ALSO, अदिश UDFs की योजनाएँ क्रियान्वित की जाती हैं। इसका मतलब यह है कि अगर यूडीएफ में निष्पादन योजनाएं हैं, तो प्रश्नों को सूँघने वाले पैरामीटर में भागना संभव है। ऐसे परिदृश्यों के लिए जहां EXECवाक्य रचना का उपयोग करना संभव है , फिर उस निष्पादन के लिएWITH RECOMPILE संकलित मूल्य को अनदेखा करने के लिए विकल्प का उपयोग करना भी संभव है । उदाहरण के लिए:

सेट अप:

GO
CREATE FUNCTION dbo.TestUDF (@Something INT)
RETURNS INT
AS 
BEGIN
   DECLARE @Ret INT;
   SELECT @Ret = COUNT(*)
   FROM   sys.indexes si
   WHERE  si.[index_id] = @Something;

   RETURN @Ret;
END;
GO

परीक्षा:

DECLARE @Val INT;

SET @Val = dbo.TestUDF(1);
SELECT @Val;

EXEC @Val = dbo.TestUDF 0 -- uses compiled value of (1)
SELECT @Val;

EXEC @Val = dbo.TestUDF 0 WITH RECOMPILE; -- uses compiled value of (0)
SELECT @Val;

EXEC @Val = dbo.TestUDF 3 -- uses compiled value of (1)
SELECT @Val;

4

मुझे लगता है कि अनुमतियों में अंतर इसलिए है क्योंकि आप वास्तव में स्केलर-वैल्यू-यूज़र-डिफ़ाइंड फ़ंक्शन को EXEC के साथ संग्रहीत प्रक्रियाओं की तरह ही लागू कर सकते हैं (जो मुझे SQL Server 2000 पुस्तकें ऑनलाइन में खोदने तक का एहसास नहीं हुआ था, जहां उन्होंने उपयोगकर्ता-परिभाषित फ़ंक्शन शुरू किए थे) , फिर भी आप वास्तव में तालिका स्रोत के रूप में उनसे चयन नहीं कर सकते। उदाहरण के लिए:

DECLARE @date datetime
EXEC @date = dbo.first_day_of_month '8/14/2015'
SELECT @date

इस स्थिति में, dbo.first_day_of_month उपयोगकर्ता-परिभाषित फ़ंक्शन है। मुझे नहीं पता कि आप कभी इस तरह से एक समारोह का आयोजन क्यों करेंगे, लेकिन मैं अनुमान लगाऊंगा कि उन्होंने स्थिरता बनाए रखने के लिए चयन के बजाय EXECUTE की अनुमति की आवश्यकता है। आजकल यह शायद संगतता सामान के रूप में पकड़े हुए है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.