《卸甲筆記》-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
- Scala與Java差異(三)之函式Java函式
- Oracle中exists和in的效能差異Oracle
- [譯]React函式元件和類元件的差異React函式元件
- python:dis包中dis()和Bytecode()函式的差異Python函式
- SQL Server 2017 各版本之間的差異SQLServer
- 談談 mysql和oracle的使用感受 -- 差異MySqlOracle
- UDP和TCP的差異UDPTCP
- Bootstrap和Tailwind CSS之間的差異?bootAICSS
- 工作流和BPM之間的差異
- 【譯】 React官方:函式元件與類元件的差異 ?React函式元件
- openGauss資料與PostgreSQL的差異對比SQL
- 線上json差異比較工具--遞迴比較兩個json的節點和值的差異,並支援差異數預覽和逐個檢視差異JSON遞迴
- Scala與Java差異(五)之Map與TupleJava
- Akka 和 Storm 的設計差異ORM
- Oracle與GreatSQL差異:更改唯一索引列OracleSQL索引
- MySQL和PostgreSQL在多表連線演算法上的差異MySql演算法
- IRequiresSessionState和IReadOnlySessionState應用上的一些差異UISession
- 技術分享|SQL和 NoSQL資料庫之間的差異:MySQL(VS)MongoDB資料庫MySqlMongoDB
- 聊聊t-io和netty的差異Netty
- 不同資料庫SQL語法差異資料庫SQL
- Spark和Hadoop之間的主要技術差異和選擇SparkHadoop
- Git比對檔案之間的差異Git
- 反向代理與正向代理差異分析
- 【譯】框架與庫的差異框架
- mac和windows執行maven命令的差異MacWindowsMaven
- MariaDB 和 GreatSQL 效能差異背後的真相SQL
- Linux和Windows的差異?0基礎需知!LinuxWindows
- 不同系統裡同一Customizing activity的顯示差異分析
- 示例解讀 Python 2 和 Python 3 之間的主要差異Python
- CentOS/RHEL 7:Chrony vs NTP(ntpd和chronyd之間的差異)CentOS
- js中split,splice,slice方法之間的差異。JS
- list對比差異
- Gradle中的差異化構建Gradle
- 能動性:知識分子和企業家之間的差異
- 國內外的ERP系統存在顯著的差異,差在哪?
- TiDB與MySQL的SQL差異及執行計劃簡析TiDBMySql
- MOBA遊戲分析:LOL和DO他的核心設計邏輯差異遊戲
- 解讀操作型MDM和分析型MDM的差異與過渡WG