เราพบปัญหาที่น่าสนใจกับ SQL Server พิจารณาตัวอย่างการทำซ้ำต่อไปนี้:
CREATE TABLE #test (s_guid uniqueidentifier PRIMARY KEY);
INSERT INTO #test (s_guid) VALUES ('7E28EFF8-A80A-45E4-BFE0-C13989D69618');
SELECT s_guid FROM #test
WHERE s_guid = '7E28EFF8-A80A-45E4-BFE0-C13989D69618'
AND s_guid <> NEWID();
DROP TABLE #test;
โปรดลืมสักครู่ว่าs_guid <> NEWID()
สภาพดูเหมือนจะไร้ประโยชน์โดยสิ้นเชิง - นี่เป็นเพียงตัวอย่างที่ไม่สำคัญ เนื่องจากความน่าจะเป็นของการNEWID()
จับคู่ค่าคงที่ที่กำหนดมีค่าน้อยมากจึงควรประเมินเป็น TRUE ทุกครั้ง
แต่มันก็ไม่ได้ การเรียกใช้คิวรีนี้มักจะส่งคืน 1 แถว แต่บางครั้ง (ค่อนข้างบ่อยมากกว่า 1 ครั้งจาก 10) จะคืนค่า 0 แถว ฉันได้ทำซ้ำกับ SQL Server 2008 ในระบบของฉันและคุณสามารถทำซ้ำออนไลน์กับซอที่เชื่อมโยงด้านบน (SQL Server 2014)
เมื่อดูที่แผนการดำเนินการพบว่าเครื่องมือวิเคราะห์แบบสอบถามแยกเงื่อนไขออกเป็นs_guid < NEWID() OR s_guid > NEWID()
:
... ซึ่งอธิบายได้อย่างสมบูรณ์ว่าเหตุใดจึงล้มเหลวในบางครั้ง (ถ้า ID ที่สร้างขึ้นครั้งแรกมีขนาดเล็กลงและอีกรายการหนึ่งใหญ่กว่า ID ที่กำหนด)
คือ SQL Server ได้รับอนุญาตในการประเมินA <> B
เป็นA < B OR A > B
แม้ว่าหนึ่งของการแสดงออกไม่เป็นกำหนด? ถ้าใช่เอกสารนั้นอยู่ที่ไหน หรือว่าเราพบข้อผิดพลาด?
น่าสนใจให้AND NOT (s_guid = NEWID())
ผลแผนการดำเนินการเดียวกัน (และผลลัพธ์แบบสุ่มเดียวกัน)
เราพบปัญหานี้เมื่อนักพัฒนาซอฟต์แวร์ต้องการยกเว้นแถวที่เลือกและใช้:
s_guid <> ISNULL(@someParameter, NEWID())
เป็น "ทางลัด" สำหรับ:
(@someParameter IS NULL OR s_guid <> @someParameter)
ฉันกำลังมองหาเอกสารและ / หรือการยืนยันข้อผิดพลาด รหัสไม่ใช่ทุกสิ่งที่เกี่ยวข้องดังนั้นจึงไม่จำเป็นต้องแก้ไขปัญหา