जब से आप जाहिरा तौर पर SQL सर्वर 2016 का उपयोग कर रहे हैं, मैं एक और ' संभव ' विकल्प को बाहर फेंकना चाहूंगा - SESSION_CONTEXT
।
SQL सर्वर 2016 मेंSESSION_CONTEXT
लियोनार्ड लोबेल के लेख, शेयरिंग स्टेट इन एसक्यूएल सर्वर 2016 के बारे में कुछ बहुत अच्छी जानकारी है।
कुछ प्रमुख बिंदुओं का सारांश:
यदि आप कभी भी एक डेटाबेस कनेक्शन के जीवन भर में सभी संग्रहीत प्रक्रियाओं और बैचों में सत्र राज्य साझा करना चाहते हैं, तो आप प्यार करने जा रहे हैं SESSION_CONTEXT
। जब आप SQL Server 2016 से जुड़ते हैं, तो आपको एक स्टेटफुल डिक्शनरी मिलती है, या जिसे अक्सर स्टेट बैग के रूप में जाना जाता है, कुछ जगह जहाँ आप वैल्यूज़ स्टोर कर सकते हैं, जैसे स्ट्रिंग्स और नंबर, और फिर इसे एक कुंजी द्वारा पुनः प्राप्त करते हैं जिसे आप असाइन करते हैं। के मामले में SESSION_CONTEXT
, कुंजी किसी भी स्ट्रिंग है, और मान एक sql_variant है, जिसका अर्थ है कि यह विभिन्न प्रकारों को समायोजित कर सकता है।
एक बार जब आप किसी चीज़ को स्टोर कर लेते हैं SESSION_CONTEXT
, तो कनेक्शन बंद होने तक यह वहीं रहता है। यह डेटाबेस में किसी भी तालिका में संग्रहीत नहीं है, यह सिर्फ स्मृति में रहता है जब तक कि कनेक्शन जीवित रहता है। और कोई भी और सभी टी-एसक्यूएल कोड जो संग्रहीत प्रक्रियाओं, ट्रिगर, फ़ंक्शंस, या जो भी हो, के अंदर चल रहा है, जो भी आप साझा करते हैं उसे साझा कर सकते हैं
SESSION_CONTEXT
।
इस तरह की निकटतम चीज़ जो अब तक हमारे पास है CONTEXT_INFO
, जो आपको 128 बाइट्स तक की एक एकल बाइनरी वैल्यू को स्टोर करने और साझा करने की अनुमति देती है, जो आपके द्वारा प्राप्त किए जाने वाले शब्दकोश की तुलना में बहुत कम लचीला है SESSION_CONTEXT
, जो विभिन्न डेटा के कई मूल्यों का समर्थन करता है प्रकार के।
SESSION_CONTEXT
उपयोग करने के लिए आसान है, बस एक वांछित कुंजी द्वारा मूल्य संग्रहीत करने के लिए sp_set_session_context को कॉल करें। जब आप ऐसा करते हैं, तो आप पाठ्यक्रम की कुंजी और मूल्य की आपूर्ति करते हैं, लेकिन आप read_only पैरामीटर को भी सही पर सेट कर सकते हैं। यह सत्र संदर्भ में मान को लॉक करता है, ताकि इसे कनेक्शन के शेष जीवनकाल के लिए नहीं बदला जा सके। इसलिए, उदाहरण के लिए, डेटाबेस कनेक्शन स्थापित करने के बाद कुछ सत्र संदर्भ मान सेट करने के लिए इस संग्रहीत कार्यविधि को कॉल करने के लिए क्लाइंट एप्लिकेशन के लिए यह आसान है। यदि एप्लिकेशन ऐसा करते समय read_only पैरामीटर सेट करता है, तो संग्रहीत कार्यविधियाँ और अन्य T-SQL कोड जो तब सर्वर पर निष्पादित होता है, केवल मान को पढ़ सकते हैं, वे क्लाइंट पर चल रहे एप्लिकेशन द्वारा निर्धारित नहीं किया जा सकता।
परीक्षण के रूप में, मैंने एक सर्वर लॉगिन ट्रिगर बनाया जो कुछ CONTEXT_SESSION
जानकारी सेट करता है - एक के लिए SESSION_CONTEXT
सेट किया गया था @read_only
।
DROP TRIGGER IF EXISTS [InitializeSessionContext] ON ALL SERVER
GO
CREATE TRIGGER InitializeSessionContext ON ALL SERVER
FOR LOGON AS
BEGIN
--Initialize context information that can be altered in the session
EXEC sp_set_session_context @key = N'UsRegion'
,@value = N'Southeast'
--Initialize context information that cannot be altered in the session
EXEC sp_set_session_context @key = N'CannotChange'
,@value = N'CannotChangeThisValue'
,@read_only = 1
END;
मैंने एक नए उपयोगकर्ता के रूप में लॉग इन किया और SESSION_CONTEXT
जानकारी निकालने में सक्षम था :
DECLARE @UsRegion varchar(20)
SET @UsRegion = CONVERT(varchar(20), SESSION_CONTEXT(N'UsRegion'))
SELECT DoThat = @UsRegion
DECLARE @CannotChange varchar(20)
SET @CannotChange = CONVERT(varchar(20), SESSION_CONTEXT(N'CannotChange'))
SELECT DoThat = @CannotChange
मैंने भी 'read_only' संदर्भ जानकारी को बदलने का प्रयास किया:
EXEC sp_set_session_context @key = N'CannotChange'
,@value = N'CannotChangeThisValue'
और एक त्रुटि मिली:
Msg 15664, Level 16, State 1, Procedure sp_set_session_context, Line 1 [बैच स्टार्ट लाइन 8] सत्र संदर्भ में कुंजी 'CannotChange' सेट नहीं कर सकता। इस सत्र के लिए कुंजी को read_only के रूप में सेट किया गया है।
लॉगिन ट्रिगर ( इस पोस्ट से ) के बारे में एक महत्वपूर्ण नोट !
लॉगऑन ट्रिगर प्रभावी रूप से सभी उपयोगकर्ताओं के लिए डेटाबेस इंजन के सफल कनेक्शन को रोक सकता है, जिसमें sysadmin फिक्स्ड सर्वर भूमिका के सदस्य भी शामिल हैं। जब एक लॉगऑन ट्रिगर कनेक्शन को रोक रहा है, तो sysadmin निश्चित सर्वर भूमिका के सदस्य समर्पित प्रशासक कनेक्शन का उपयोग करके, या न्यूनतम कॉन्फ़िगरेशन मोड में डेटाबेस इंजन को शुरू करके कनेक्ट कर सकते हैं (-f)
एक संभावित दोष यह है कि यह सत्र संदर्भ उदाहरण विस्तृत (प्रति डेटाबेस नहीं) भरता है। इस बिंदु पर, एकमात्र विकल्प जो मैं सोच सकता हूं:
Session_Context
डेटाबेस नाम के साथ प्रीफ़िक्स करके अपने नाम-मूल्य जोड़े को नाम दें ताकि दूसरे डेटाबेस में उसी प्रकार के नाम के लिए टकराव का कारण न हो। यह Session_Context
सभी उपयोगकर्ताओं के लिए सभी नाम-मानों को पूर्व-परिभाषित करने की समस्या को हल नहीं करता है ।
- जब लॉगिन ट्रिगर में आग लग जाती है, तो आपके पास
EventData
(xml) तक पहुंच होती है, जिसका उपयोग आप लॉगिन उपयोगकर्ता को निकालने के लिए कर सकते हैं और उसके आधार पर, आप विशिष्ट Session_Context
नाम-मूल्य जोड़े बना सकते हैं ।