2009-06-17 20 views
441

एक और सवाल मैं किसी को तैनात में मुझसे कहा था कि वहाँ के बीच एक अंतर है कि:MySQL: @Variable बनाम चर। क्या फर्क पड़ता है?

@variable 

और:

variable 
MySQL में

। उन्होंने यह भी बताया कि कैसे एमएसएसक्यूएल में बैच स्कोप है और माईएसक्यूएल में सत्र का दायरा है। क्या कोई मेरे लिए इस पर विस्तार कर सकता है?

उत्तर

552

MySQL में user-defined variables की अवधारणा है।

वे ढीले टाइप किए गए चर हैं जिन्हें किसी सत्र में कहीं भी प्रारंभ किया जा सकता है और सत्र समाप्त होने तक उनका मान रखें।

वे एक @ संकेत के साथ prepended कर रहे हैं इस तरह:

SET @var = 1 

SELECT @var2 := 2 

आप MySQL में एक संग्रहीत प्रक्रिया का विकास कब: @var

आप एक प्रश्न में एक SET बयान के साथ इस चर को प्रारंभ या अंदर कर सकते हैं , आप इनपुट पैरामीटर पास कर सकते हैं और स्थानीय चर घोषित कर सकते हैं:

DELIMITER // 

CREATE PROCEDURE prc_test (var INT) 
BEGIN 
    DECLARE var2 INT; 
    SET var2 = 1; 
    SELECT var2; 
END; 
// 

DELIMITER ; 

ये चर किसी भी उपसर्ग के साथ प्रीपेड नहीं हैं।

एक प्रक्रिया चर और एक सत्र-विशिष्ट उपयोगकर्ता परिभाषित चर के बीच अंतर यह है कि प्रक्रिया चर NULL हर बार प्रक्रिया कहा जाता है इसे पुनः शुरू किया गया है, जबकि सत्र-विशिष्ट चर नहीं है:

CREATE PROCEDURE prc_test() 
BEGIN 
    DECLARE var2 INT DEFAULT 1; 
    SET var2 = var2 + 1; 
    SET @var2 = @var2 + 1; 
    SELECT var2, @var2; 
END; 

SET @var2 = 1; 

CALL prc_test(); 

var2 @var2 
--- --- 
2  2 


CALL prc_test(); 

var2 @var2 
--- --- 
2  3 


CALL prc_test(); 

var2 @var2 
--- --- 
2  4 

जैसा कि आप देख सकते हैं, var2 (प्रक्रिया परिवर्तनीय) प्रक्रिया को हर बार पुन: प्रारंभ किया जाता है, जबकि @var2 (सत्र-विशिष्ट चर) नहीं है। इन "सत्र चर" कर रहे हैं;

(उपयोगकर्ता-निर्धारित वेरिएबल के अलावा, MySQL भी कुछ पूर्वनिर्धारित "प्रणाली चर", इस तरह के @@session.sql_mode के रूप में "वैश्विक चर" जैसे @@global.port या "सत्र चर" हो सकता है जो है सत्र-विशिष्ट उपयोगकर्ता-परिभाषित चर से असंबंधित।)

+36

यह भी ध्यान रखें कि वैश्विक चर उपलब्ध हैं: उदाहरण के लिए 'SELECT @@ संस्करण;' देखें। यह भी एक कारण है, 'DELIMITER @@' का उपयोग क्यों करना वास्तव में एक अच्छा विचार नहीं है। – Mchl

+12

यह नए परिणामों के लिए नए प्रश्न बनाता है ... क्या आपके उदाहरण में "var = var" और "var: = var" के बीच कोई अंतर है? – confiq

+12

@confiq: कोई नहीं है। – Quassnoi

64

MySQL में, @variableuser-defined variable इंगित करता है। आप अपना खुद का परिभाषित कर सकते हैं।

SET @a = 'test'; 
SELECT @a; 

संग्रहीत कार्यक्रमों के बाहर, एक variable, @ के बिना, एक system variable है, जो आप अपने आप को परिभाषित नहीं कर सकते हैं।

इस चर का दायरा पूरे सत्र है। इसका मतलब है कि डेटाबेस के साथ आपका कनेक्शन मौजूद है, फिर भी चर का उपयोग किया जा सकता है।

यह एमएसएसक्यूएल के विपरीत है, जहां चर केवल क्वेरी के मौजूदा बैच (संग्रहीत प्रक्रिया, स्क्रिप्ट, या अन्यथा) में उपलब्ध होगा। यह एक ही सत्र में एक अलग बैच में उपलब्ध नहीं होगा।

+2

सत्र चर के साथ भ्रमित नहीं होना चाहिए, जिसमें शॉर्टैंड 'SET @@ a = 'test' है, ', cf. http://dev.mysql.com/doc/refman/5.1/en/set-statement.html – RobM

+0

@RobM, उन्हें ** सिस्टम ** चर कहा जाता है, सत्र चर नहीं। – Pacerier

+1

@Pacerier: क्या मैं दस्तावेज़ों को गलत पढ़ रहा हूं? "" "स्पष्ट रूप से इंगित करने के लिए कि एक चर एक सत्र चर है, SESSION, @@ सत्र।, या @@" "" – RobM

9

एमएसएसक्यूएल की आवश्यकता है कि प्रक्रियाओं के भीतर चर के रूप में DECLARED हो और लोग @Variable वाक्यविन्यास (DECLARE @TEXT VARCHAR (25) = 'text') का उपयोग करें। इसके अलावा, एमएस प्रक्रिया में किसी भी ब्लॉक के भीतर घोषित करने की अनुमति देता है, मेरे एसक्यूएल के विपरीत जो शीर्ष पर सभी डेक्लेयर की आवश्यकता होती है।

कमांड लाइन पर अच्छा होने पर, मुझे लगता है कि MySQL में संग्रहित प्रक्रियाओं के भीतर "set = @variable" का उपयोग जोखिम भरा है। दायरे की सीमाओं में कोई गुंजाइश और चर नहीं रहते हैं। यह जावास्क्रिप्ट में "var" उपसर्ग के बिना घोषित किए जाने वाले चर के समान है, जो तब वैश्विक नामस्थान हैं और अप्रत्याशित टकराव और ओवरराइट बनाते हैं।

मुझे उम्मीद है कि mySQL पर अच्छे लोग एक संग्रहित प्रक्रिया के भीतर विभिन्न ब्लॉक स्तरों पर DECLARE @ Variable की अनुमति देंगे। @ (हस्ताक्षर पर) पर ध्यान दें। @ साइन उपसर्ग तालिका कॉलम नामों से परिवर्तनीय नामों को अलग करने में मदद करता है - क्योंकि वे अक्सर समान होते हैं। निस्संदेह, कोई भी हमेशा "v" या "l_" उपसर्ग जोड़ सकता है, लेकिन @ चिह्न एक आसान और संक्षिप्त तरीका है, जिसमें वेरिएबल नाम कॉलम से मेल खाता है, जिसे आप डेटा को बिना क्लॉबर्ड किए से निकाल सकते हैं।

MySQL संग्रहीत प्रक्रियाओं के लिए नया है और उन्होंने अपने पहले संस्करण के लिए एक अच्छा काम किया है। यह देखने के लिए एक याचिका होगी कि वे इसे यहां कहां लेते हैं और भाषा के सर्वर पक्ष पहलुओं को परिपक्व देखते हैं।

3

सिद्धांत रूप में, मैं संग्रहीत प्रक्रियाओं के भीतर UserDefinedVariables (@ के साथ प्रीपेड) का उपयोग करता हूं। इससे जीवन आसान हो जाता है, खासकर जब मुझे दो या अधिक संग्रहीत प्रक्रियाओं में इन चरों की आवश्यकता होती है। जब मैं सिस्टम वैरिएबल (प्रीपेन्ड @ के बिना) का उपयोग करता हूं, तो बस मुझे केवल एक संग्रहित प्रक्रिया के भीतर एक चर की आवश्यकता होती है।

@Xybo: मुझे समझ में नहीं आ रहा है कि स्टोर्ड प्रसंस्करण में @variables का उपयोग क्यों जोखिम भरा होना चाहिए। क्या आप कृपया "गुंजाइश" और "सीमाएं" को थोड़ा सा आसान समझ सकते हैं (मेरे लिए एक नौसिखिया के रूप में)?

+3

यह मूल सॉफ़्टवेयर इंजीनियरिंग सिद्धांतों का उल्लंघन करता है। कृपया कोड की एथर लाइन न लिखें जब तक आपको पता न हो कि वास्तव में क्या गुंजाइश है, और वैश्विक चर का उपयोग करने का उपयोग करना आम तौर पर एक भयानक विचार है। जब मैंने 101 प्रोग्रामिंग कक्षाएं लीं, क्योंकि मुझे लगता है कि बहुत कुछ के लिए वैश्विक का उपयोग करना एक स्वचालित "एफ" होगा। विशेष अपवाद हैं, लेकिन एक सामान्य नियम के रूप में - बस यह मत करो! – BuvinJ

+0

क्यों? - @Variables हर MySQL-Book में बिल्कुल आम हैं। – Peter

+0

निश्चित रूप से, कोई फ़ंक्शन कॉल, प्रक्रियाएं, ट्रिगर्स इत्यादि के साथ "फ्लैट" स्क्रिप्ट में और यदि आप बस उस साधारण स्क्रिप्ट को निष्पादित करने जा रहे हैं, या कमांड का सीमित सेट और फिर सत्र समाप्त करें (जिससे आपके ग्लोबल्स को नष्ट कर दिया जाए) । यह मामला, आगे बढ़ें और यदि आप चाहें तो उनका इस्तेमाल करें। लेकिन उन्हें एक समारोह के अंदर उपयोग न करें! यदि आप बस Google वैश्विक चर या दायरे को तुरंत इस विचार के लिए विशाल समर्थन प्राप्त करेंगे कि वे सार्वभौमिक रूप से डूब गए हैं। यहां एक प्रारंभिक बिंदु है: http://wiki.c2.com/?GlobalVariablesAreBad या अधिक सामान्य स्पष्टीकरण के लिए: https://en.wikipedia.org/wiki/Global_variable – BuvinJ

संबंधित मुद्दे