[नोट:यदि आप इस उत्तर को कम करने जा रहे हैं, तो कृपया एक टिप्पणी छोड़ कर बताएं कि क्यों। इसे पहले ही कई बार कम किया जा चुका है, और अंत में ypercube (धन्यवाद) ने कम से कम एक कारण बताया। मैं उत्तर को नहीं हटा सकता क्योंकि यह स्वीकार कर लिया गया है, इसलिए आप इसे सुधारने में भी मदद कर सकते हैं।]
Microsoft पर इस एक्सचेंज के अनुसार, GETDATE()
SQL सर्वर 2005 में एक क्वेरी के भीतर स्थिर होने से गैर-नियतात्मक में स्विच किया गया। पूर्व-निरीक्षण में, मुझे नहीं लगता कि यह सटीक है। मुझे लगता है कि यह SQL सर्वर 2005 से पहले पूरी तरह से गैर-नियतात्मक था और फिर SQL सर्वर 2005 के बाद से "गैर-नियतात्मक रनटाइम स्थिरांक" नामक किसी चीज़ में हैक किया गया। बाद के वाक्यांश का वास्तव में अर्थ "एक क्वेरी के भीतर स्थिर" लगता है।
(और GETDATE()
स्पष्ट रूप से और गर्व से गैर-नियतात्मक के रूप में परिभाषित किया गया है, जिसमें कोई क्वालिफायर नहीं है।)
काश, SQL सर्वर में, गैर-नियतात्मक का अर्थ यह नहीं है कि प्रत्येक पंक्ति के लिए एक फ़ंक्शन का मूल्यांकन किया जाता है। SQL सर्वर वास्तव में इस विषय पर बहुत कम दस्तावेज़ीकरण के साथ इसे अनावश्यक रूप से जटिल और अस्पष्ट बनाता है।
व्यवहार में फ़ंक्शन कॉल का मूल्यांकन तब किया जाता है जब क्वेरी संकलित होने पर एक बार के बजाय क्वेरी चल रही होती है और हर बार इसे कॉल करने पर इसका मान बदल जाता है। व्यवहार में, GETDATE()
प्रत्येक अभिव्यक्ति के लिए केवल एक बार मूल्यांकन किया जाता है जहां इसका उपयोग किया जाता है -- निष्पादन समय . पर संकलित समय . के बजाय . हालांकि, माइक्रोसॉफ्ट rand()
puts डालता है और getdate()
एक विशेष श्रेणी में, जिसे गैर-नियतात्मक रनटाइम स्थिरांक फ़ंक्शन कहा जाता है। इसके विपरीत, Postgres ऐसे हुप्स से कूदता नहीं है, यह केवल उन कार्यों को कॉल करता है जिनका "स्थिर" के रूप में निष्पादित होने पर स्थिर मूल्य होता है।
मार्टिन स्मिथ की टिप्पणी के बावजूद, SQL सर्वर दस्तावेज़ीकरण इस मामले पर स्पष्ट नहीं है -- GETDATE()
को "नॉनडेटर्मिनिस्टिक" और "गैर-नियतात्मक रनटाइम स्थिरांक" दोनों के रूप में वर्णित किया गया है, लेकिन उस शब्द को वास्तव में समझाया नहीं गया है। उदाहरण के लिए, जिस स्थान पर मुझे यह शब्द मिला है, दस्तावेज़ीकरण में अगली पंक्तियाँ कहती हैं कि उपश्रेणियों में गैर-नियतात्मक कार्यों का उपयोग न करें। यह "नॉनडेटर्मिनिस्टिक रनटाइम स्थिरांक" के लिए मूर्खतापूर्ण सलाह होगी।
मैं एक क्वेरी के भीतर भी एक स्थिरांक के साथ एक चर का उपयोग करने का सुझाव दूंगा, इसलिए आपके पास एक सुसंगत मूल्य है। यह इरादे को भी स्पष्ट करता है:आप क्वेरी के अंदर एक ही मान चाहते हैं। एक ही प्रश्न में, आप कुछ ऐसा कर सकते हैं:
select . . .
from (select getdate() as now) params cross join
. . .
दरअसल, यह एक सुझाव है जिसे चाहिए क्वेरी में केवल एक बार मूल्यांकन करें, लेकिन अपवाद हो सकते हैं। भ्रम पैदा होता है क्योंकि getdate()
सभी अलग-अलग पंक्तियों पर समान मान लौटाता है -- लेकिन यह अलग-अलग कॉलम में अलग-अलग मान लौटा सकता है। प्रत्येक अभिव्यक्ति getdate()
. के साथ स्वतंत्र रूप से मूल्यांकन किया जाता है। यदि आप दौड़ते हैं तो यह स्पष्ट है:
select rand(), rand()
from (values (1), (2), (3)) v(x);
एक संग्रहीत प्रक्रिया के भीतर, आप एक चर में एक ही मान रखना चाहेंगे। क्या होता है यदि संग्रहीत कार्यविधि को आधी रात बीतने के साथ चलाया जाता है, और तिथि बदल जाती है? इसका परिणामों पर क्या प्रभाव पड़ता है?
प्रदर्शन के लिए, मेरा अनुमान है कि दिनांक/समय लुकअप न्यूनतम है और एक क्वेरी के लिए प्रति अभिव्यक्ति एक बार होती है क्योंकि क्वेरी चलना शुरू हो जाती है। यह वास्तव में एक प्रदर्शन समस्या नहीं होनी चाहिए, बल्कि एक कोड-संगति समस्या से अधिक होनी चाहिए।