ORACLE, 你把空字串怎麼了?
腦海中一直存著清晰的一幕,牙牙學語摸索SQL語法的青澀少年Jeffrey,端坐SQL大師Ryan的跟前,聽著諄諄教誨:
孩子,閉上眼晴,用原力去感受... 在SQL世界裡NULL具有獨特的魔力,VARCHAR欄位儲存著NULL或是空字串? 在意義上是絕對不同的...
後來在DB、Web領域打滾多年,我常常採行這項Schema設計理念:NULL代表使用者未曾輸入過任何資料,空字串則代表使用者輸入了,但未指定任何值。在SQL Server的世界裡,這條鐵律一直運行得很好,直到我遇到了ORACLE...
今天在寫一個動態的SQL複合條件查詢,為了簡化起見,用了以下的技巧:
SELECT SomeColumns....
FROM SomeTable
WHERE (:userId = '' OR UserIdCol = :userId)
AND SomeOtherCriteria...
我打的如意算盤是,如果userId傳入空字串,就不限定UserIdCol的值;否則就透過指定userId的方式,只傳回UserIdCol=:userId的結果。
測試了一下,將:userId參數設為空字串,理應列出所有的資料。很好!! 什麼都沒傳回來... orz
Debug了一下,才發現在ORACLE裡,根本沒有空字串這種東西,空字串會被視為NULL。因此,'' = ''等同於NULL = NULL,等於比對不會傳回True或False,而是傳回NULL。
接著,用Google找到相關說明。雖然違背了ANSI SQL 92的定義,但ORACLE的確會將空字串當作NULL處理,導致了非我預期的結果。
由於不能因為這點特性要求更換DataBase,山不轉路轉,路不轉人轉,上述的SQL語法要改寫成:
SELECT SomeColumns....
FROM SomeTable
WHERE (:userId IS NULL OR UserIdCol = :userId)
AND SomeOtherCriteria...
繼續幹活去!