有兩個不合理的資料表,一個表是原料表Material,一個表是庫存表Stock,這兩個表合并也不會有資料冗餘。但是要在不改動這兩個表基礎上,解決一個問題。
問題是什麼呢?先交代一下背景:
1、原料表是需要通過“基礎資訊錄入”插入記錄的,而庫存表是通過“入庫操作”插入記錄的;
2、此外還有一個產品表,產品表通過一個產品明細表跟原材料表關聯,產品ID與原材料ID是一對多的關係;
3、出庫時通過選擇一個產品ID,將該產品對應的原材料記錄自動填滿到出庫明細中,這裡使用了一個【視圖】。
問題是:當一個產品裡包含一個無庫存的原材料,那麼選擇該產品時,那個無庫存的原材料將不會被填充到出庫明細中。
原因是:經過分析發現,無庫存的原材料在【視圖】中的庫存表的原材料ID、庫存表的庫存ID、庫存表的倉庫ID、庫存表的庫存單價和庫存表的庫存數量都為NULL;而我在查詢條件中用到這裡的倉庫ID,在結果使用上用到了這裡的庫存單價和庫存數量;因此倉庫ID為NULL的記錄將不會出現在結果集中,進而導致產品中的原材料明細沒有被全部填充到出庫明細中。
解決辦法是:使用ISNULL函數(初學者朋友注意,這裡不是IS NULL,中間有一個空格的是判斷值是否為空白,而這個函數中間沒有空格),對可能為NULL值的欄位使用ISNULL函數並賦予設定值;如果在視圖建立過程中,一定要為ISNULL函數結果設定一個列別名。
函數基本用法
功能:使用指定的替換值替換NULL。
文法:ISNULL(check_expression,replacement_value)。
參數:check_expression是被檢測是否為NULL的運算式(包括欄位),可以是任何類型;replacement_value是當check_expression為NULL時替換的值,replacement_value必須是能夠隱式轉換成check_expression類型的類型(見後面說明)。
傳回值:如果check_expression為NULL,返回replacement_value值;如果check_expression不為NULL,則返回check_expression值。
說明:1、不要使用ISNULL函數尋找NULL值;
2、當check_expression為NULL時,若replacement_value類型與check_expression類型不一致,看是否能隱式轉換,如果能隱式轉換,那麼不報錯且轉換類型後傳回值,如果不能隱式轉換,那麼執行SQL語句時直接報錯
舉例:前面提到的庫存表庫存數量為NULL,在視圖查詢語句中,我對庫存數量列使用該函數,庫存數量列的類型為int,當我將replacement_value值設為0,語句正常執行且返回0;當我設為'0'時,語句亦正常執行,但是返回0而不是'0';當我設為'a'時,語句終止執行並報錯“類型無法隱式轉換”(類似這個意思)。
最後,這個函數很簡單,只是筆者不會,如果您也不會,那麼可以多掌握一個基本知識點,如果您已經會了,那麼以後遇到視圖或者聯集查詢時,要記得對可能為NULL的列使用此函數。
鄙視自己一下,因為沒打算髮到部落格園首頁,所以沒想到這篇文章還會被閱讀。因此一個重要的問題沒有說明,本篇涉及ISNULL函數的說明全都來自網路上一個網友的原創博文,只是例子是筆者自己的,看了那個網友的博文以後,解決了筆者的實際問題,因此記錄下來以備後查。在此對於那個網友表示衷心的謝意和歉意!