MySQL: @variable बनाम चर। क्या फर्क पड़ता है?


500

एक अन्य प्रश्न में मैंने पोस्ट किया है कि किसी ने मुझे बताया कि इसके बीच अंतर है:

@variable

तथा:

variable

MySQL में। उन्होंने यह भी उल्लेख किया कि कैसे MSSQL में बैच गुंजाइश है और MySQL में सत्र गुंजाइश है। क्या कोई मेरे लिए इस पर विस्तार कर सकता है?


1
मैं MsSQL से परिचित हूं और इसलिए इस तरह का सवाल पूछने के लिए कभी सोचा नहीं था। यहाँ उपलब्ध कराए गए जवाबों ने मुझे कुछ ऐसा बना दिया जिसके बारे में मेरे पास कोई आईडिया नहीं था !! Thx ..
केन

जवाबों:


623

MySQLउपयोगकर्ता-परिभाषित चर की अवधारणा है ।

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

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

आप इस वैरिएबल को एक SETस्टेटमेंट के साथ या एक क्वेरी में अंदर कर सकते हैं :

SET @var = 1

SELECT @var2 := 2

जब आप एक संग्रहीत प्रक्रिया विकसित करते हैं MySQL, तो आप इनपुट मापदंडों को पारित कर सकते हैं और स्थानीय चर घोषित कर सकते हैं:

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 भी कुछ पूर्वनिर्धारित "प्रणाली चर", जैसे कि "वैश्विक चर" हो सकता है जो है @@global.portया "सत्र चर" जैसे @@session.sql_mode, इन "सत्र चर" सत्र-विशिष्ट से संबंधित नहीं हैं उपयोगकर्ता परिभाषित चर।)


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

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

13
@confiq: कोई नहीं है।
क्वासोई

9
एक नए चेहरे के लिए एक और सवाल। जब यह @बनाम नहीं का उपयोग करने की सिफारिश की जाती है ?
पिक्सफ्रीक

73
@confiq, @Quassnoi: :=और के बीच एक महत्वपूर्ण अंतर है =, और वह यह है कि :=हर जगह एक चर-असाइनमेंट ऑपरेटर के रूप में काम करता है, जबकि =केवल SETबयानों में उस तरह से काम करता है , और हर जगह एक तुलना ऑपरेटर है। तो SELECT @var = 1 + 1;@var को अपरिवर्तित छोड़ देगा और @var के वर्तमान मूल्य के आधार पर एक बूलियन (1 या 0) वापस कर SELECT @var := 1 + 1;देगा , जबकि @var को 2 में बदल देगा, और वापस 2.
Dewi Morgan

71

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

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

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

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

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


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

@RobM, उन्हें सिस्टम वैरिएबल कहा जाता है , न कि सत्र चर।
पचेरियर

1
@ स्पेसियर: क्या मैं डॉक्स गलत पढ़ रहा हूं? "" "स्पष्ट रूप से इंगित करने के लिए कि एक चर एक सत्र चर है, इसके नाम से पहले, @@ सत्र।, या @@"। ""
RobM

5
@RobM, आप इसे गलत तरीके से पढ़ रहे हैं। पूरे पैराग्राफ के माध्यम से पढ़ें, न केवल बुलेट बिंदु के भीतर पैराग्राफ। सीधे शब्दों में, दो प्रकार के सत्र चर हैं: 1) उपयोगकर्ता-परिभाषित सत्र चर, और 2) प्रणाली-  आधारित सत्र चर। आप उपयोगकर्ता-निर्धारित सत्र चर का उपयोग करके सेट नहीं कर सकते @@। उदाहरण के लिए, set@@my_var=1, set@@session.my_var=1, और set session my_var=1क्योंकि काम करेगा नहीं my_varएक नहीं है प्रणाली चर, जबकि हम कर सकते हैं set@@big_tables=1, set@@session.big_tables=1और set session big_tables=1क्योंकि big_tablesएक प्रणाली चर रहा है।
पेसियर

1
@ गोविंदराय: क्वासोई के उत्तर में, उपसर्ग के var2बिना एक चर है @, लेकिन यह एक प्रणाली चर नहीं है: यह एक प्रक्रिया चर है। यह अनुमति है क्योंकि यह एक संग्रहीत कार्यविधि (उर्फ संग्रहीत कार्यक्रम) में है। संग्रहीत प्रक्रियाओं के बाहर, एक चर बिना @सिस्टम चर है।
15

10

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

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

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

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


3

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

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


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

क्यों? - @ MySQL-Book में वेरिएबल्स बिल्कुल सामान्य हैं।
पीटर

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

2
MySQL में, @variables वैश्विक हैं। यह आसानी से पुष्टि की जाती है। किसी फ़ंक्शन के बाहर एक सेट करें और फिर एक के अंदर इसका मूल्यांकन करें। इसके विपरीत, एक फ़ंक्शन के अंदर एक सेट करें और इसके बाहर का मूल्यांकन करें। आप देखेंगे कि फ़ंक्शन इस तरह के दायरे की सुरक्षा नहीं करता है। वे एक दूसरे के पैर की उंगलियों पर कदम रखते हैं।
BuvinJ

1
MySQL शब्दावली का उपयोग करते हुए, @@GLOBALचर और भी "वैश्विक" और कपटी हैं। वे सत्र पार करते हैं! @variables"सत्र गुंजाइश" है, इसलिए कम से कम वे उस तरीके से सीमित रहते हैं। किसी भी सामान्य भाषा में जिसे आप "ग्लोबल" स्कोप कहते हैं, हालांकि (जब वे फ़ंक्शन को पार करते हैं आदि)। "वैश्विक" की MySQL अवधारणा को शायद "सार्वभौमिक" कहा जाना चाहिए, जिसमें यह इसे चलाने की प्रक्रिया की सीमाओं से परे फैली हुई है। एक "वैश्विक" आम तौर पर एक मानक भाषा में ऐसा नहीं कर सकता है, क्योंकि प्रक्रियाएं स्मृति स्थान साझा नहीं करती हैं। यह SQL की लगातार (बनाम अस्थिर) प्रवृत्ति से उपजा है।
बुविएनजे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.