Jawaban:
Kutipan , yang merangkum dari artikel ini :
- SET adalah standar ANSI untuk penugasan variabel, SELECT tidak.
- SET hanya dapat menetapkan satu variabel pada satu waktu, SELECT dapat membuat banyak tugas sekaligus.
- Jika menetapkan dari kueri, SET hanya dapat menetapkan nilai skalar. Jika kueri mengembalikan beberapa nilai / baris maka SET akan memunculkan kesalahan. SELECT akan menetapkan salah satu nilai ke variabel dan menyembunyikan fakta bahwa beberapa nilai dikembalikan (jadi Anda mungkin tidak akan pernah tahu mengapa ada sesuatu yang salah di tempat lain - bersenang-senanglah memecahkan masalah itu)
- Saat menetapkan dari kueri jika tidak ada nilai yang dikembalikan maka SET akan menetapkan NULL, di mana SELECT tidak akan membuat penetapan sama sekali (sehingga variabel tidak akan berubah dari nilai sebelumnya)
- Sejauh perbedaan kecepatan - tidak ada perbedaan langsung antara SET dan SELECT. Namun kemampuan SELECT untuk membuat banyak penugasan dalam satu kesempatan memang memberikannya keunggulan kecepatan sedikit di atas SET.
SELECT @Int = @Int + 1, @Int = @Int + 1
jika @Int
dimulai sebagai 0, maka berakhir sebagai 2. Ini bisa sangat berguna ketika melakukan manipulasi string berturut-turut.
Saya percaya SET
standar ANSI sedangkanSELECT
tidak. Perhatikan juga perilaku berbeda SET
vs SELECT
dalam contoh di bawah ini ketika nilai tidak ditemukan.
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')
Anda akan mendapatkan @var sebagai null. Contoh yang Anda berikan bukan permintaan yang sama.
(select name from master.sys.tables where name = 'qwerty')
untuk satu, dan name from master.sys.tables where name = 'qwerty'
untuk yang lain ... apakah Anda tidak melihatnya?
(select name from master.sys.tables where name = 'qwerty')
adalah subquery skalar, dan name from master.sys.tables where name = 'qwerty'
merupakan kueri sederhana. Dua ekspresi yang berbeda tidak seharusnya menghasilkan hasil yang sama, meskipun sepertinya Anda menyiratkan bahwa mereka harus melakukannya. Jika Anda mencoba untuk mengatakan SET
dan SELECT
kata kunci memiliki implementasi yang berbeda, Anda tidak boleh menggunakan dua ekspresi yang berbeda dalam contoh Anda. msdn.microsoft.com/en-us/library/ms187330.aspx
Saat menulis pertanyaan, perbedaan ini harus diingat:
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*/
Selain dari yang ANSI dan kecepatan dll, ada perbedaan yang sangat penting yang selalu berarti bagi saya; lebih dari ANSI dan kecepatan. Jumlah bug yang saya perbaiki karena pengabaian penting ini besar. Saya mencari ini selama ulasan kode sepanjang waktu.
-- 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;
Hampir selalu, bukan itu yang dimaksudkan pengembang. Dalam contoh di atas, kueri langsung tetapi saya telah melihat pertanyaan yang cukup kompleks dan mencari tahu apakah itu akan mengembalikan nilai tunggal atau tidak, tidak sepele. Permintaan sering lebih kompleks dari ini dan kebetulan telah mengembalikan nilai tunggal. Selama pengujian pengembang semuanya baik-baik saja. Tapi ini seperti bom detak dan akan menyebabkan masalah ketika kueri mengembalikan beberapa hasil. Mengapa? Karena itu hanya akan menetapkan nilai terakhir ke variabel.
Sekarang mari kita coba hal yang sama dengan SET
:
-- Act
set @employeeId = (select e.EmployeeId from dbo.Employee e);
Anda akan menerima kesalahan:
Subquery mengembalikan lebih dari 1 nilai. Ini tidak diizinkan ketika subquery mengikuti =,! =, <, <=,>,> = Atau ketika subquery digunakan sebagai ekspresi.
Itu luar biasa dan sangat penting karena mengapa Anda ingin menetapkan beberapa "item terakhir dalam hasil" yang sepele untuk @employeeId
. Dengan select
Anda tidak akan pernah mendapatkan kesalahan dan Anda akan menghabiskan menit, jam debugging.
Mungkin, Anda mencari satu ID dan SET
akan memaksa Anda untuk memperbaiki kueri Anda. Dengan demikian Anda dapat melakukan sesuatu seperti:
-- Act
-- Notice the where clause
set @employeeId = (select e.EmployeeId from dbo.Employee e where e.EmployeeId = 1);
print @employeeId;
Membersihkan
drop table Employee;
Sebagai kesimpulan, gunakan:
SET
: Ketika Anda ingin menetapkan nilai tunggal ke suatu variabel dan variabel Anda adalah untuk nilai tunggal.SELECT
: Ketika Anda ingin menetapkan beberapa nilai ke suatu variabel. Variabel dapat berupa tabel, tabel temp atau variabel tabel dll.