《卸甲筆記》-PostgreSQL和Oracle的SQL差異分析之五:函式的差異(一)
PostgreSQL是世界上功能最強大的開源資料庫,在國內得到了越來越多機構和開發者的青睞和應用。隨著PostgreSQL的應用越來越廣泛,Oracle向PostgreSQL資料庫的資料遷移需求也越來越多。資料庫之間資料遷移的時候,首先是遷移資料,然後就是SQL、儲存過程、序列等程式中不同的資料庫中資料的使用方式的轉換。下面根據自己的理解和測試,寫了一些SQL以及資料庫物件轉換方面的文章,不足之處,尚請多多指教。
1、NULL判斷函式
Oracle的NULL判斷函式是 nvl(A, B) 和 coalesce 兩個函式。nvl(A, B) 是判斷如果A不為NULL,則返回A, 否則返回B。引數需要是相同型別的,或者可以自動轉換成相同型別的, 否則需要顯式轉換。而 coalese 引數可以有多個,返回第一個不為NULL的引數。而引數必須為相同型別的 ,不會自動轉換。
PostgreSQL中沒有nvl函式。但是有coalesce函式。用法和Oracle的一樣。可以使用coalesce來轉換Oracle的nvl和coalesce。引數需要使用相同型別,或者可以轉換成相同型別的。否則需要手動轉換。
Oracle NULL判斷函式
SQL> select * from o_test;
VALUE1 VALUE2 VALUE3
---------- ---------- --------------
111111 05-8月 -16
1 31-7月 -16
2 222222
SQL> select nvl(value1, `Hello`) value1 from o_test;
select nvl(value1, `Hello`) value1 from o_test
*
第 1 行出現錯誤:
ORA-01722: 無效數字
SQL> select nvl(value1, `10000`) value1 from o_test;
VALUE1
----------
10000
1
2
SQL> select nvl(value2, `Hello`) value2 from o_test;
VALUE2
----------
111111
Hello
222222
SQL> select nvl(value3, `2010-1-1`) value3 from o_test;
select nvl(value3, `2010-1-1`) value3 from o_test
*
第 1 行出現錯誤:
ORA-01861: 文字與格式字串不匹配
SQL> select nvl(value3, to_date( `2010-01-01`,`YYYY-MM-DD`)) value3 from o_test;
VALUE3
--------------
05-8月 -16
31-7月 -16
01-1月 -10
SQL> select coalesce(value1, `10000`) value1 from o_test;
select coalesce(value1, `10000`) value1 from o_test
*
第 1 行出現錯誤:
ORA-00932: 資料型別不一致: 應為 NUMBER, 但卻獲得 CHAR
SQL> select coalesce(value1, 10000) value1 from o_test;
VALUE1
----------
10000
1
2
SQL> select coalesce(value2, ``, `Hello John`) value2 from o_test;
VALUE2
----------
111111
Hello John
222222
SQL> select coalesce(value3,``, to_date( `2010-01-01`,`YYYY-MM-DD`)) value3 from o_test;
select coalesce(value3,``, to_date( `2010-01-01`,`YYYY-MM-DD`)) value3 from o_test
*
第 1 行出現錯誤:
ORA-00932: 資料型別不一致: 應為 DATE, 但卻獲得 CHAR
SQL> select coalesce(value3, null, to_date( `2010-01-01`,`YYYY-MM-DD`)) value3 from o_test;
VALUE3
--------------
05-8月 -16
31-7月 -16
01-1月 -10
PostgreSQL NULL判斷函式
postgres=# select * from p_test;
value1 | value2 | value3
--------+--------+---------------------
| 11111 | 2010-01-01 00:00:00
1 | | 2010-01-01 00:00:00
2 | 22222 |
(3 行記錄)
postgres=# select coalesce(value1, `Hello`) value1 from p_test;
錯誤: 無效的整數型別輸入語法: "Hello"
第1行select coalesce(value1, `Hello`) value1 from p_test;
^
postgres=# select coalesce(value1, `10000`) value1 from p_test;
value1
--------
10000
1
2
(3 行記錄)
postgres=# select coalesce(value2, null, `Hello world`) value2 from p_test;
value2
-------------
11111
Hello world
22222
(3 行記錄)
postgres=# select coalesce(value3, null, `2012-10-10`) value3 from p_test;
value3
---------------------
2010-01-01 00:00:00
2016-08-05 10:01:32
2012-10-10 00:00:00
(3 行記錄)
postgres=# select coalesce(value3, null, `2012-10-A`) value3 from p_test;
錯誤: 無效的型別 timestamp 輸入語法: "2012-10-A"
第1行select coalesce(value3, null, `2012-10-A`) value3 from p_te...
^
2、字串連線
2.1、字串連線符( || )
Oracle的字串連線符(||) 和 PostgreSQL的字串連線符(||)的用法基本相同,不同的地方是
1、當連線的引數有null的時候,Oracle中,null 的連線效果類似於空字串(“),而PostgreSQL中, 連線的引數中有null的, 連線結果統一都是null。
2、當幾個引數都是數字的時候,Oracle會自動把數字轉換為字串。這個和Oracle內部的自動型別轉換有關係。而PostgreSQL中,幾個引數中至少有一個應該為字串,否則會報錯。
資料遷移的時候,對於Oracle的 A || B 可以使用PostgreSQL的coalesce( A, “) || coalesce( B, “)形式來轉換。
Oracle 字串連線符( || )
SQL> select `abc` || `def` value from dual;
VALUE
------
abcdef
SQL> select 123 || 456 value from dual;
VALUE
------
123456
SQL> select null || 456 value from dual;
VAL
---
456
SQL> select null || `abcdef` value from dual;
VALUE
------
abcdef
SQL> select length(null || null) value from dual;
VALUE
----------
PostgreSQL 字串連線符( || )
postgres=# select `abc` || `def` as value;
value
--------
abcdef
(1 行記錄)
postgres=# select 123 || 456 as value;
錯誤: 操作符不存在: integer || integer
第1行select 123 || 456 as value;
^
提示: 沒有匹配指定名稱和引數型別的操作符. 您也許需要增加明確的型別轉換.
postgres=# select 123||`456` as value;
value
--------
123456
(1 行記錄)
postgres=# select null || 456 as value ;
value
-------
(1 行記錄)
postgres=# select null || `abcdef` as value;
value
-------
(1 行記錄)
postgres=# select length(null || null) as value ;
value
-------
(1 行記錄)
2.2、字串連線函式concat
Oracle的concat函式類似於字串連線符(||),但只能夠連線兩個引數。引數需要是字串型別,或者可以自動轉換成字串型別。
PostgreSQL中也內建了這個方法。
需要注意的是,Oracle的concat,如果兩個引數都是null, 則結果是null。而PostgreSQL中,如果兩個引數都是null,則 結果是空字串(“)。因為PostgreSQL的concat方法內部對於引數做了coalesce(null, “)處理。
Oracle concat
SQL> select concat(`abc`,`def`) from dual;
CONCAT
------
abcdef
SQL> select concat(123, 456) from dual;
CONCAT
------
123456
SQL> select concat(null, 456) value from dual;
VAL
---
456
SQL> select concat(null, `abc`) value from dual;
VAL
---
abc
SQL> select concat(null, null) value from dual;
V
-
SQL> select length(concat(null, null)) value from dual;
VALUE
----------
SQL> select * from o_test;
VALUE1 VALUE2 VALUE3
---------- ---------- --------------
111111 05-8月 -16
1 31-7月 -16
2 222222
SQL> select concat(value3, value2) from o_test;
CONCAT(VALUE3,VALUE2)
------------------------
05-8月 -16111111
31-7月 -16
222222
PostgreSQL 字串連線函式
postgres=# select concat(`abc`,`def`);
concat
--------
abcdef
(1 行記錄)
postgres=# select concat(123, 456);
concat
--------
123456
(1 行記錄)
postgres=# select concat(null, 456) as value;
value
-------
456
(1 行記錄)
postgres=# select concat(null, `abc`) as value;
value
-------
abc
(1 行記錄)
postgres=# select concat(null, null) as value;
value
-------
(1 行記錄)
postgres=# select length(concat(null, null)) as value;
value
-------
0
(1 行記錄)
postgres=# select * from p_test;
value1 | value2 | value3
--------+--------+---------------------
| 11111 | 2010-01-01 00:00:00
1 | | 2016-08-05 10:01:32
2 | 22222 |
(3 行記錄)
postgres=# select concat(value3, value2) as value from p_test;
value
--------------------------
2010-01-01 00:00:0011111
2016-08-05 10:01:32
22222
(3 行記錄)
相關文章
- 《卸甲筆記》-PostgreSQL和Oracle的SQL差異分析之五:函式的差異(五)筆記SQLOracle函式
- 《卸甲筆記》-PostgreSQL和Oracle的SQL差異分析之五:函式的差異(三)筆記SQLOracle函式
- 《卸甲筆記》-PostgreSQL和Oracle的SQL差異分析之一:外連線筆記SQLOracle
- 《卸甲筆記》-PostgreSQL和Oracle的SQL差異分析之四:特殊字元和符號筆記SQLOracle字元符號
- PostgreSQL與Oracle的sql差異SQLOracle
- Scala與Java差異(三)之函式Java函式
- [譯]React函式元件和類元件的差異React函式元件
- now&sysdate函式差異函式
- Oracle中exists和in的效能差異Oracle
- For Update操作分析——不同Oracle版本之間的差異研究Oracle
- delphi中回撥函式差異函式
- UDP和TCP的差異UDPTCP
- vue和react的差異VueReact
- ERP差異來源和差異處理
- Bootstrap和Tailwind CSS之間的差異?bootAICSS
- PHP 轉 Node 筆記(一. 談談兩者的差異)PHP筆記
- 談談 mysql和oracle的使用感受 -- 差異MySqlOracle
- 工作流和BPM之間的差異
- Scala與Java差異(五)之Map與TupleJava
- 【譯】 React官方:函式元件與類元件的差異 ?React函式元件
- SQL server差異備份和還原SQLServer
- SQL Server 2017 各版本之間的差異SQLServer
- 線上json差異比較工具--遞迴比較兩個json的節點和值的差異,並支援差異數預覽和逐個檢視差異JSON遞迴
- 系統之間差異
- 【讀書筆記】XHTML與HTML5的差異筆記HTML
- openGauss資料與PostgreSQL的差異對比SQL
- MySQL和PostgreSQL在多表連線演算法上的差異MySql演算法
- jquery版本中的差異jQuery
- .net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常OracleSQLServer
- 《卸甲筆記》-PostgreSQL和Oracle的資料型別的對比系列五:其它型別筆記SQLOracle資料型別
- Java和C++的基本差異(轉)JavaC++
- [轉載] SQL server 差異備份和還原SQLServer
- ChromeDriver版本差異Chrome
- 中西IT差異論
- Oracle與GreatSQL差異:更改唯一索引列OracleSQL索引
- 技術分享|SQL和 NoSQL資料庫之間的差異:MySQL(VS)MongoDB資料庫MySqlMongoDB
- IRequiresSessionState和IReadOnlySessionState應用上的一些差異UISession
- Git比對檔案之間的差異Git