ความหมายของทั้งสองประโยคนั้นแตกต่างกัน:
- ตัวแรกไม่ได้ตั้งค่าของตัวแปรถ้าไม่พบแถว
- ตัวที่สองตั้งค่าตัวแปรเสมอรวมถึง null ถ้าไม่พบแถว
การสแกนอย่างต่อเนื่องจะสร้างแถวว่าง (ไม่มีคอลัมน์!) ซึ่งจะส่งผลให้ตัวแปรมีการปรับปรุงในกรณีที่ไม่มีสิ่งใดที่ตรงกับจากตารางฐาน การเข้าร่วมด้านซ้ายช่วยให้แน่ใจว่าแถวว่างยังมีชีวิตอยู่การเข้าร่วม การกำหนดตัวแปรสามารถคิดได้ว่าเกิดขึ้นที่โหนดรูทของแผนการดำเนินการ
การใช้ SELECT @result
-- Set initial value
DECLARE @result uniqueidentifier = {guid 'FE2CA909-1162-4C6C-A7AC-33B257E28539'};
-- @result does not change
SELECT @result = AccountId
FROM Accounts
WHERE AccountId={guid '7AD4D33C-1ED7-4183-B7F3-48C33D666525'};
SELECT @result;
การใช้ SET @result
-- Set initial value
DECLARE @result uniqueidentifier = {guid 'FE2CA909-1162-4C6C-A7AC-33B257E28539'};
-- @result set to null
SET @result =
(
SELECT AccountId
FROM Accounts
WHERE AccountId={guid '7AD4D33C-1ED7-4183-B7F3-48C33D666525'}
);
SELECT @result;
แผนการดำเนินการ
ไม่มีแถวมาถึงโหนดรูทดังนั้นจึงไม่มีการกำหนดเกิดขึ้น
แถวมาถึงที่โหนดรูตเสมอดังนั้นการกำหนดตัวแปรจึงเกิดขึ้น
การสแกนค่าคงที่พิเศษและลูปซ้อนด้านนอกด้านซ้ายเข้าร่วมไม่มีอะไรน่ากังวล การเข้าร่วมโดยเฉพาะราคาถูกเนื่องจากรับประกันว่าจะพบหนึ่งแถวในอินพุตภายนอกและอย่างน้อยหนึ่งแถว (ในตัวอย่างของคุณ) ในอินพุตภายใน
มีวิธีอื่น ๆ เพื่อให้แน่ใจว่าแถวถูกสร้างขึ้นจากแบบสอบถามย่อยเพื่อให้แน่ใจว่าการกำหนดตัวแปรเกิดขึ้น หนึ่งคือการใช้การรวมสเกลาร์ซ้ำซ้อน (ไม่มีกลุ่มตามข้อ):
-- Set initial value
DECLARE @result uniqueidentifier = {guid 'FE2CA909-1162-4C6C-A7AC-33B257E28539'};
-- @result set to null
SET @result =
(
SELECT MAX(AccountId)
FROM Accounts
WHERE AccountId={guid '7AD4D33C-1ED7-4183-B7F3-48C33D666525'}
);
SELECT @result;
สังเกตว่าการรวมสเกลาร์จะสร้างแถวแม้ว่ามันจะไม่ได้รับอินพุตก็ตาม
เอกสารอ้างอิง:
หากคำสั่ง SELECT ไม่มีการส่งคืนแถวตัวแปรจะเก็บค่าปัจจุบันไว้ หากการแสดงออกเป็นแบบสอบถามย่อยสเกลาร์ที่ไม่ส่งคืนค่าใด ๆ ตัวแปรจะถูกตั้งค่าเป็น NULL
สำหรับการกำหนดตัวแปรเราขอแนะนำให้คุณใช้ SET @local_variable แทน SELECT @local_variable
อ่านเพิ่มเติม: