ভেরিয়েবল বরাদ্দকালে SET বনাম SELECT?


290

টি-এসকিউএলে ভেরিয়েবল নির্ধারণের সময় SETএবং SELECTবিবৃতিগুলির মধ্যে পার্থক্যগুলি কী ?

উত্তর:


411

উদ্ধৃতি , যা এই নিবন্ধ থেকে সংক্ষিপ্তসার :

  1. ভেরিয়েবল অ্যাসাইনমেন্টের জন্য এসইটি হ'ল এএনএসআই স্ট্যান্ডার্ড, নির্বাচন নয়।
  2. SET একবারে কেবল একটি ভেরিয়েবল বরাদ্দ করতে পারে, SELECT একবারে একাধিক অ্যাসাইনমেন্ট দিতে পারে।
  3. যদি কোনও কোয়েরি থেকে বরাদ্দ করা হয় তবে এসইটি কেবল একটি স্কেলারের মান নির্ধারণ করতে পারে। যদি কোয়েরিতে একাধিক মান / সারি ফিরে আসে তবে SET ত্রুটি বাড়িয়ে তুলবে। নির্বাচনটি ভেরিয়েবলের মধ্যে একটি মান নির্ধারণ করে এবং একাধিক মান ফিরে আসার বিষয়টি লুকিয়ে রাখে (সুতরাং আপনি সম্ভবত কখনই বুঝতে পারবেন না যে কেন অন্য কোথাও ভুল হচ্ছে - মজাদার সমস্যা সমাধানে মজা করুন)
  4. যখন কোনও কোয়েরি থেকে নির্ধারণের সময় যদি কোনও মান ফেরত না থাকে তবে SET NULL প্রদান করবে, যেখানে SELECT মোটেও কার্যনির্বাহীকরণ করবে না (সুতরাং ভেরিয়েবলটি তার আগের মান থেকে পরিবর্তন করা হবে না)
  5. যতদূর গতির পার্থক্য - SET এবং SELECT এর মধ্যে সরাসরি কোনও পার্থক্য নেই। তবে একটি শটে একাধিক অ্যাসাইনমেন্ট করার জন্য SELECT এর ক্ষমতা সেটকে এটির চেয়ে সামান্য গতির সুবিধা দেয়।

3
আমি ডাউনওয়েট করিনি, তবে নিম্নলিখিতগুলি একেবারেই সঠিক নয়: "যতদূর গতির পার্থক্য রয়েছে - এসইটি এবং সিলেক্টের মধ্যে কোনও সরাসরি পার্থক্য নেই"। আপনি যদি একাধিক মানকে একক নির্বাচিত করে থাকেন তবে মাল্টিপল সেটগুলির মাধ্যমে এটি আরও দ্রুততর হতে পারে। গুগল আপ "এক নির্বাচনের সাথে একাধিক ভেরিয়েবল দ্রুতগতিতে কাজ করে"
এ কে

14
@ অ্যালেক্সকুজনেটসভ: বাক্যটি পরে বলছে ঠিক তাই
ওএমজি পনিস

3
@ ওএমজি পনিস: এটি 10 ​​গুণ দ্রুত বা তার বেশি হতে পারে, সুতরাং এটি "সামান্য গতির সুবিধা" কিনা তা আমি নিশ্চিত নই।
একে 20

2
বিশেষত যখন ওয়ে-লুপ ব্যবহার করার সময়, আমি ওয়ান-সিলেক্ট বনাম বহু-সেট ব্যবহার করে আমার সমস্ত ভেরিয়েবলগুলি সেট / পুনরায় আরম্ভ করে বিশাল পারফরম্যান্স লাভ দেখেছি। আমি একবারে একবারে সিলেক্ট করে আমার ভেরিয়েবল-লজিককে একীভূত করতে পারি: উদাহরণ:, 0 হিসাবে শুরু SELECT @Int = @Int + 1, @Int = @Int + 1হলে @Intএটি 2 হিসাবে শেষ হয় success ধারাবাহিক স্ট্রিং-ম্যানিপুলেশনগুলি করার সময় এটি খুব কার্যকর হতে পারে।
মাইকটাইভি

পারফরম্যান্স পার্থক্য সম্পর্কে আকর্ষণীয় আলোচনা। যদি নির্বাচনের মাধ্যমে একাধিক মান নির্ধারণ করা দ্রুত হয় (কোড এবং কার্যকর করতে) তবে পয়েন্ট 4 এড়ানোর একটি ব্যর্থ উপায় (আপনার ভেরিয়েবলের মান পরিবর্তন করতে ব্যর্থ হয়েছে যদি ক্যোয়ারী নাল ফেরায়) নির্বাচনের পূর্বে আপনার ভেরিয়েবলকে স্পষ্টভাবে সেট করতে হবে। আপনি যখন এটি ফ্যাক্টর করেন, তখন দু'জন পারফরম্যান্সের জন্য কীভাবে তুলনা করে? (পার্শ্ব দ্রষ্টব্য: আপনি যদি কোনও প্রশ্নের উত্তর বাতিল করে দেয় তবে আপনার ভেরিয়েবলটি বাতিল করে না দেওয়ার বাছাই করার যৌক্তিকতা আমি বুঝতে পারি না When আপনি কখন তা চান?)
youcantryreachingme

155

আমি বিশ্বাস করি 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' */

4
+1 বোঝার জন্য একবার চালানো আরও ভাল, চেক করা, খেলতে, মুখস্থ করতে যা কেবল পড়তে হয় তবে অন্যান্য উত্তরগুলি কেবল পাঠ্য
জেনাডি ভ্যানিন Геннадий

4
আপনি যদি বাস্তবে ব্যবহার করেন তবে select @var = (select name from master.sys.tables where name = 'qwerty')আপনি @var নਾਲ হিসাবে পাবেন get আপনি যে উদাহরণটি দিচ্ছেন সেটি একই ক্যোয়ারী নয়।
জ্যাক

4
আপনার (select name from master.sys.tables where name = 'qwerty')একটির name from master.sys.tables where name = 'qwerty'জন্য এবং অন্যটির জন্য ... আপনি কি তা দেখছেন না?
জ্যাক

4
@ জ্যাক: আমি ডেমো করার চেষ্টা করছি তার জন্য প্রতিটিই সঠিক বাক্য গঠন; অন্তর্নিহিত কোয়েরি যখন কোনও ফল দেয় না তখন কোনও ভেরিয়েবলের জন্য একটি মান নির্ধারণ করতে SET বনাম নির্বাচন নির্বাচন করার মধ্যে পার্থক্য।
জো স্টেফেনেলি

5
(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
জ্যাক

27

প্রশ্নগুলি লেখার সময়, এই পার্থক্যটি মনে রাখা উচিত:

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*/

খুব সুন্দর,
সংশ্লেষ

8

একজন এএনএসআই এবং গতি ইত্যাদি বাদে, একটি গুরুত্বপূর্ণ পার্থক্য রয়েছে যা সর্বদা আমার কাছে গুরুত্বপূর্ণ; এএনএসআই এবং গতির চেয়ে বেশি। এই গুরুত্বপূর্ণ দৃষ্টিভঙ্গির কারণে আমি যে বাগের সংখ্যা স্থির করেছি সেগুলি বড়। কোড রিভিউগুলির সময় আমি এটি সন্ধান করি।

-- 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 টির বেশি মান ফেরত দিয়েছে। যখন subquery =,! =, <, <=,>,> = অনুসরণ করে বা যখন subquery একটি এক্সপ্রেশন হিসাবে ব্যবহৃত হয় তখন এটি অনুমোদিত হয় না।

এটি আশ্চর্যজনক এবং খুব গুরুত্বপূর্ণ কারণ আপনি কেন কিছু তুচ্ছ "ফলাফলের ফলাফল হিসাবে শেষ আইটেম" অর্পণ করতে চান @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: আপনি যখন একটি ভেরিয়েবল একাধিক মান নির্ধারণ করতে চান। ভেরিয়েবলটি কোনও টেবিল, টেম্প টেবিল বা টেবিলের পরিবর্তনশীল ইত্যাদি হতে পারে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.