Yanıtlar:
Bu makaleden özetleyen alıntı :
- SET, değişken ataması için ANSI standardıdır, SELECT değildir.
- SET aynı anda yalnızca bir değişken atayabilir, SELECT aynı anda birden fazla atama yapabilir.
- Bir sorgudan atama yapılıyorsa, SET sadece skaler bir değer atayabilir. Sorgu birden çok değer / satır döndürürse SET bir hata oluşturur. SELECT, değişkenlerden birine değişkenlerden birini atar ve birden çok değerin döndürüldüğü gerçeğini gizler (bu nedenle, başka bir yerde neden bir şeyin yanlış gittiğini asla bilemezsiniz - bu sorun giderme işleminde eğlenin)
- Döndürülen değer yoksa bir sorgudan atama yaparken SET, NULL atayacaktır; burada SELECT atamayı hiç yapmayacaktır (bu nedenle değişken önceki değerinden değiştirilmeyecektir)
- Hız farkları kadar - SET ve SELECT arasında doğrudan fark yoktur. Ancak SELECT'in bir çekimde birden fazla atama yapabilmesi, SET'e göre hafif bir hız avantajı sağlar.
SELECT @Int = @Int + 1, @Int = @Int + 1
başlarsa @Int
, 2 olarak biter. Bu, ardışık dize manipülasyonları yaparken çok yararlı olabilir.
SET
ANSI standardı olduğuna inanıyorum , oysa SELECT
değil. Ayrıca , bir değer bulunamadığında aşağıdaki örnekte SET
vs.'nin farklı davranışına dikkat edin 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')
@var null olarak alınır. Verdiğiniz örnek aynı sorgu değil.
(select name from master.sys.tables where name = 'qwerty')
biri için ve name from master.sys.tables where name = 'qwerty'
diğeri için ... bunu görmüyorum?
(select name from master.sys.tables where name = 'qwerty')
skaler bir alt name from master.sys.tables where name = 'qwerty'
sorgudur ve basit bir sorgudur. İki farklı ifadenin aynı sonuçları üretmesi beklenmiyor, ancak öyle olması gerektiğini ima ediyorsunuz. SET
Ve SELECT
anahtar kelimelerin farklı uygulamaları olduğunu söylemeye çalışıyorsanız , örneklerinizde iki farklı ifade kullanmamalısınız . msdn.microsoft.com/tr-tr/library/ms187330.aspx
Sorgu yazarken, bu fark göz önünde bulundurulmalıdır:
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*/
Birinin ANSI ve hız vs. olmasının yanı sıra, benim için her zaman önemli olan çok önemli bir fark var; ANSI ve hızdan daha fazlası. Bu önemli göz ardı nedeniyle sabitlediğim hata sayısı çok fazla. Ben her zaman kod gözden geçirme sırasında bak.
-- 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;
Neredeyse her zaman, geliştiricinin istediği bu değildir. Yukarıda, sorgu düz ileri ama oldukça karmaşık sorguları gördüm ve tek bir değer döndürüp dönmeyeceğini bulmak önemsiz değil. Sorgu genellikle bundan daha karmaşıktır ve şans eseri tek bir değer döndürmektedir. Geliştirici testi sırasında her şey yolunda. Ancak bu bir tik tak bomba gibidir ve sorgu birden fazla sonuç döndürdüğünde sorunlara neden olur. Neden? Çünkü değişkene sadece son değeri atayacaktır.
Şimdi aynı şeyi deneyelim SET
:
-- Act
set @employeeId = (select e.EmployeeId from dbo.Employee e);
Bir hata mesajı alırsınız:
Alt sorgu 1'den fazla değer döndürdü. Alt sorgu =,! =, <, <=,>,> = Öğesini izlediğinde veya alt sorgu ifade olarak kullanıldığında buna izin verilmez.
Bu şaşırtıcı ve çok önemli, çünkü neden önemsiz bir "sonuçta son öğe" atamak istersiniz @employeeId
. İle select
herhangi bir hatayı asla ve dakika geçirecek, saat ayıklama.
Belki de tek bir kimlik arıyorsunuz ve SET
sorgunuzu düzeltmeye zorlayacaksınız. Böylece şöyle bir şey yapabilirsiniz:
-- Act
-- Notice the where clause
set @employeeId = (select e.EmployeeId from dbo.Employee e where e.EmployeeId = 1);
print @employeeId;
Temizlemek
drop table Employee;
Sonuç olarak, şunları kullanın:
SET
: Bir değişkene tek bir değer atamak istediğinizde ve değişkeniniz tek bir değer içindir.SELECT
: Bir değişkene birden çok değer atamak istediğinizde. Değişken bir tablo, geçici tablo veya tablo değişkeni vb. Olabilir.