जवाबों:
उद्धरण , जो इस लेख से सारांशित करता है :
- SET वेरिएबल असाइनमेंट के लिए ANSI मानक है, SELECT नहीं है।
- SET एक समय में केवल एक ही चर असाइन कर सकता है, SELECT एक ही बार में कई कार्य कर सकता है।
- यदि किसी क्वेरी से असाइन किया जाता है, तो SET केवल एक स्केलर मान प्रदान कर सकता है। यदि क्वेरी कई मान / पंक्तियाँ लौटाती है तो SET एक त्रुटि देगा। चयन चर में से किसी एक मान को असाइन करेगा और इस तथ्य को छिपाएगा कि कई मान लौटाए गए हैं (इसलिए आपको कभी पता नहीं चलेगा कि कहीं और गलत क्यों हो रहा है - मजेदार समस्या निवारण है)
- जब क्वेरी से असाइन किया जाता है यदि कोई मान नहीं लौटाया जाता है, तो SET NULL को असाइन करेगा, जहां SELECT असाइनमेंट बिल्कुल नहीं करेगा (इसलिए चर को उसके पिछले मूल्य से नहीं बदला जाएगा)
- जहाँ तक गति अंतर - SET और SELECT के बीच कोई प्रत्यक्ष अंतर नहीं हैं। हालाँकि एक शॉट में कई असाइनमेंट करने की सेलेक्ट की क्षमता इसे SET पर थोड़ी गति का लाभ देती है।
SELECT @Int = @Int + 1, @Int = @Int + 1
यदि @Int
0 के रूप में शुरू किया गया है, तो यह 2 के रूप में समाप्त होता है। क्रमिक स्ट्रिंग-जोड़तोड़ करते समय यह बहुत उपयोगी हो सकता है।
मेरा मानना SET
है कि एएनएसआई मानक है जबकि SELECT
ऐसा नहीं है। मूल्य नहीं मिलने पर नीचे के उदाहरण में SET
बनाम के विभिन्न व्यवहार पर भी ध्यान दें SELECT
।
declare @var varchar(20)
set @var = 'Joe'
set @var = (select name from master.sys.tables where name = 'qwerty')
select @var /* @var is now NULL */
set @var = 'Joe'
select @var = name from master.sys.tables where name = 'qwerty'
select @var /* @var is still equal to 'Joe' */
select @var = (select name from master.sys.tables where name = 'qwerty')
करते हैं तो आपको null के रूप में @var मिलेगा। आप जो उदाहरण दे रहे हैं, वही क्वेरी नहीं है।
(select name from master.sys.tables where name = 'qwerty')
एक के लिए है, और name from master.sys.tables where name = 'qwerty'
दूसरे के लिए ... क्या आपको वह दिखाई नहीं देता?
(select name from master.sys.tables where name = 'qwerty')
एक अदिश उपश्रेणी है, और name from master.sys.tables where name = 'qwerty'
एक सरल क्वेरी है। दो अलग-अलग अभिव्यक्तियों को एक ही परिणाम नहीं माना जाता है, हालांकि ऐसा लगता है कि आप इसका अर्थ लगा रहे हैं कि उन्हें होना चाहिए। यदि आप यह कहना चाह रहे हैं कि कीवर्ड्स SET
और SELECT
कार्यान्वयन अलग-अलग हैं, तो आपको अपने उदाहरणों में दो अलग-अलग अभिव्यक्तियों का उपयोग नहीं करना चाहिए । msdn.microsoft.com/en-us/library/ms187330.aspx
प्रश्न लिखते समय, इस अंतर को ध्यान में रखा जाना चाहिए:
DECLARE @A INT = 2
SELECT @A = TBL.A
FROM ( SELECT 1 A ) TBL
WHERE 1 = 2
SELECT @A
/* @A is 2*/
---------------------------------------------------------------
DECLARE @A INT = 2
SET @A = (
SELECT TBL.A
FROM ( SELECT 1 A) TBL
WHERE 1 = 2
)
SELECT @A
/* @A is null*/
एक एएनएसआई और गति आदि होने के अलावा, एक बहुत महत्वपूर्ण अंतर है जो हमेशा मेरे लिए मायने रखता है; ANSI और गति से अधिक। इस महत्वपूर्ण अनदेखी के कारण मेरे द्वारा तय किए गए बग की संख्या बड़ी है। मैं हर समय कोड समीक्षा के दौरान इसकी तलाश करता हूं।
-- Arrange
create table Employee (EmployeeId int);
insert into dbo.Employee values (1);
insert into dbo.Employee values (2);
insert into dbo.Employee values (3);
-- Act
declare @employeeId int;
select @employeeId = e.EmployeeId from dbo.Employee e;
-- Assert
-- This will print 3, the last EmployeeId from the query (an arbitrary value)
-- Almost always, this is not what the developer was intending.
print @employeeId;
लगभग हमेशा, वह नहीं है जो डेवलपर का इरादा है। उपरोक्त में, क्वेरी सीधे आगे है लेकिन मैंने ऐसे प्रश्नों को देखा है जो काफी जटिल हैं और यह पता लगा रहे हैं कि क्या यह एकल मान लौटाएगा या नहीं, यह तुच्छ नहीं है। क्वेरी अक्सर इससे अधिक जटिल होती है और संयोग से यह एकल मान लौटा रही है। डेवलपर परीक्षण के दौरान सब ठीक है। लेकिन यह एक टिक करने वाले बम की तरह है और जब कई परिणाम आएंगे तो यह समस्या पैदा करेगा। क्यों? क्योंकि यह केवल चर को अंतिम मान देगा।
आइए अब उसी चीज को आजमाते हैं SET
:
-- Act
set @employeeId = (select e.EmployeeId from dbo.Employee e);
आपको एक त्रुटि प्राप्त होगी:
सबक्वेरी 1 से अधिक मूल्य पर लौटी। यह अनुमति नहीं है जब उप-वर्ग =,! =, <, <=,>,> = या जब उप-अभिव्यक्ति का उपयोग किया जाता है।
यह आश्चर्यजनक और बहुत महत्वपूर्ण है क्योंकि आप कुछ तुच्छ "अंतिम आइटम को परिणाम में" क्यों असाइन करना चाहते हैं @employeeId
। आपके साथ select
कभी कोई त्रुटि नहीं होगी और आप मिनट, घंटे डिबगिंग खर्च करेंगे।
शायद, आप एक एकल आईडी की तलाश कर रहे हैं और SET
आपको अपनी क्वेरी को ठीक करने के लिए मजबूर करेंगे। इस प्रकार आप कुछ ऐसा कर सकते हैं:
-- Act
-- Notice the where clause
set @employeeId = (select e.EmployeeId from dbo.Employee e where e.EmployeeId = 1);
print @employeeId;
साफ - सफाई
drop table Employee;
निष्कर्ष में, उपयोग करें:
SET
: जब आप किसी वैरिएबल को सिंगल वैल्यू असाइन करना चाहते हैं और आपका वैरिएबल सिंगल वैल्यू के लिए है।SELECT
: जब आप एक चर के लिए कई मान निर्दिष्ट करना चाहते हैं। चर एक तालिका, अस्थायी तालिका या तालिका चर आदि हो सकता है।