NULL的資料型別(二)
以前寫過一篇文章,透過DECODE來確定NULL的預設資料型別,前幾天在開發版發現newkid透過不同的方法得出了相同的答案。
NULL的資料型別:http://yangtingkun.itpub.net/post/468/50132
ITPUB中原貼:http://www.itpub.net/thread-1328690-1-1.html
NULL比較特殊,任何資料型別的空都用NULL來表示,因此NULL可以是任何資料型別。所以在一般情況下,NULL也是不會體現出具體的型別的。
不過有時候還是可以從一些特殊的情況判斷出Oracle給NULL確定的預設型別。
比如newkid給出的CREATE VIEW的例子:
SQL> CREATE VIEW V_NULL AS
2 SELECT NULL N
3 FROM DUAL;
檢視已建立。
SQL> DESC V_NULL
名稱 是否為空? 型別
------------------------------------------------------- -------- --------
N VARCHAR2
和我前一篇得出的結果是一樣的,Oracle在某些情況下,會把NULL當作VARCHAR2型別來處理。
而且同時還發現幾個有意思的現象:
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT SYSDATE N FROM DUAL
3 UNION ALL
4 SELECT NULL FROM DUAL;
檢視已建立。
SQL> DESC V_TEST
名稱 是否為空? 型別
------------------------------------------------------- -------- --------------
N DATE
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT SYSDATE N FROM DUAL
3 UNION ALL
4 SELECT '' FROM DUAL;
SELECT SYSDATE N FROM DUAL
*
第 2 行出現錯誤:
ORA-01790: 表示式必須具有與對應表示式相同的資料型別
Oracle會檢查UNION ALL包含的兩個查詢結果的資料型別是否匹配,如果不匹配就會出現上面的錯誤。其實在以前的文章中已經提到過,空字串‘‘是NULL的字元型別表現形式,具體的描述可以參考:http://yangtingkun.itpub.net/post/468/245697
由於NULL可以轉換為任意的型別,因此Oracle檢查到NULL後,會根據另一個查詢的型別來確定最終的型別,但是空字串‘‘已經表現出了字元型別,因此和另一個查詢的DATE型別不相符因此報錯。
重點是下面的結果:
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT NULL N FROM DUAL
3 UNION ALL
4 SELECT '' FROM DUAL;
檢視已建立。
SQL> DESC V_TEST
名稱 是否為空? 型別
------------------------------------------------------- -------- ----------------
N VARCHAR2
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT '' N FROM DUAL
3 UNION ALL
4 SELECT NULL FROM DUAL;
檢視已建立。
SQL> DESC V_TEST
名稱 是否為空? 型別
------------------------------------------------------- -------- ----------------
N CHAR
兩個SQL的區別只是UNION ALL兩個查詢的順序,而恰恰就是這個順序決定了最終檢視中欄位的型別。從這一個SQL可以得出三個推論,一、UNION ALL查詢由前面的SQL作為型別的主導;二、空字串’’的預設型別是CHAR;三、NULL的預設型別是VARCHAR2。
除了上面的結果外,TO_NUMBER(NULL)也比較有意思:
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT TO_NUMBER(NULL) N FROM DUAL
3 UNION ALL
4 SELECT TO_CHAR(NULL) FROM DUAL;
檢視已建立。
SQL> DESC V_TEST
名稱 是否為空? 型別
------------------------------------------------------- -------- ---------------------
N VARCHAR2
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT TO_NUMBER(NULL) N FROM DUAL
3 UNION ALL
4 SELECT TO_DATE(NULL) FROM DUAL;
檢視已建立。
SQL> DESC V_TEST
名稱 是否為空? 型別
------------------------------------------------------- -------- ---------------------
N DATE
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT TO_CHAR(NULL) N FROM DUAL
3 UNION ALL
4 SELECT TO_NUMBER(NULL) FROM DUAL;
SELECT TO_CHAR(NULL) N FROM DUAL
*
第 2 行出現錯誤:
ORA-01790: 表示式必須具有與對應表示式相同的資料型別
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT TO_CHAR(NULL) N FROM DUAL
3 UNION ALL
4 SELECT TO_DATE(NULL) FROM DUAL;
SELECT TO_CHAR(NULL) N FROM DUAL
*
第 2 行出現錯誤:
ORA-01790: 表示式必須具有與對應表示式相同的資料型別
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT TO_DATE(NULL) N FROM DUAL
3 UNION ALL
4 SELECT TO_NUMBER(NULL) FROM DUAL;
SELECT TO_DATE(NULL) N FROM DUAL
*
第 2 行出現錯誤:
ORA-01790: 表示式必須具有與對應表示式相同的資料型別
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT TO_DATE(NULL) N FROM DUAL
3 UNION ALL
4 SELECT TO_CHAR(NULL) FROM DUAL;
SELECT TO_DATE(NULL) N FROM DUAL
*
第 2 行出現錯誤:
ORA-01790: 表示式必須具有與對應表示式相同的資料型別
似乎在UNION ALL第一個查詢中指定的TO_NUMBER沒有起到確定NUMBER型別的作用,而如果緩衝CAST則不會出現這種情況:
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT CAST(NULL AS NUMBER) N FROM DUAL
3 UNION ALL
4 SELECT TO_CHAR(NULL) FROM DUAL;
SELECT CAST(NULL AS NUMBER) N FROM DUAL
*
第 2 行出現錯誤:
ORA-01790: 表示式必須具有與對應表示式相同的資料型別
但是要是TO_NUMBER一點作用都沒有也不盡然:
SQL> CREATE OR REPLACE VIEW V_TEST AS
2 SELECT TO_NUMBER(NULL) N FROM DUAL
3 UNION ALL
4 SELECT NULL FROM DUAL;
檢視已建立。
SQL> DESC V_TEST
名稱 是否為空? 型別
------------------------------------------------------- -------- -------------------
N NUMBER
總之,NULL總會給我們帶來一些意想不到東西。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-670308/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JavaScript基本資料型別之undefined和nullJavaScript資料型別UndefinedNull
- 二、ClickHouse 資料型別資料型別
- Swift 資料型別(二)Swift資料型別
- SSIS 資料型別 第二篇:變數的資料型別資料型別變數
- 關於0轉成null時資料型別Null資料型別
- 【SQL】18 SQL NULL 函式、SQL 通用資料型別、SQL 用於各種資料庫的資料型別SQLNull函式資料型別資料庫
- SCSS Null 型別CSSNull型別
- 二, 基本資料型別(上)資料型別
- 關於 PHP 的資料型別 (二)PHP資料型別
- [20190612]NULL的資料型別.txtNull資料型別
- Mysql資料庫學習(二):資料型別(數值型別 日期和時間型別 字串型別)MySql資料庫資料型別字串
- c#如何宣告資料結構型別為null?C#資料結構型別Null
- 二、變數與資料型別變數資料型別
- 二、資料型別和表示式資料型別
- MySQL(二) 資料庫資料型別詳解MySql資料庫資料型別
- JS 的型別(null 和 undefined 的區別)JS型別NullUndefined
- python基礎(二)—-資料型別Python資料型別
- 第二章:資料型別(續)資料型別
- 三、資料型別和表示式二資料型別
- TypeScript Null和Undefined 型別TypeScriptNullUndefined型別
- js資料型別之基本資料型別和引用資料型別JS資料型別
- 資料型別: 資料型別有哪些?資料型別
- Databricks 第9篇:Spark SQL 基礎(資料型別、NULL語義)SparkSQL資料型別Null
- JavaScript 基礎 (二) - 引用資料型別 (物件)JavaScript資料型別物件
- 從規範看ECMAScript(二):資料型別資料型別
- 第二週學習--基本資料型別資料型別
- Redis入門教程(二)— 基本資料型別Redis資料型別
- 自學PHP筆記(二)PHP資料型別PHP筆記資料型別
- 基本資料型別及其包裝類(二)資料型別
- oracle 各資料型別dump說明(二)Oracle資料型別
- Java中的基本資料型別與引用資料型別Java資料型別
- 強資料型別和弱資料型別資料型別
- 區別值型別資料和引用型別資料型別
- Oracle基本資料型別儲存格式淺析(三)——日期型別(二)Oracle資料型別
- [譯] Scala 型別的型別(二)型別
- 資料型別,型別轉換資料型別
- 二、python的邏輯運算與資料型別Python資料型別
- MySQL 的資料型別MySql資料型別