Summary of Oracle 11g database migration localization (TiDB\Dameng).

Description of functional requirements: In response to the call of national information security, the customer decided to replace the running system and database of the bureau with TiDB\Dameng from Oracle 11g. The project director of the company asked me to be responsible for the migration and transformation of the database. I added a summary of the problems encountered in the local migration and update in the following two aspects: 1. Compare the differences between Oracle and TiDB\Dameng (MySQL-like) functions, 2. Compare Oracle and TiDB\Dameng (MySQL-like) functions for missing solutions. 3. Use the DOS command to query the Mapper file that needs to be adjusted.

Compare the differences between Oracle and TiDB\Dameng (MySQL-like) functions

serial number category Oracle MySQL  Remark
1 Numeric function round(1.23456,4) round(1.23456,4) 一样:
ORACLE:select round(1.23456,4) value from dual
MYSQL:select round(1.23456,4) value
2 abs(-1) abs(-1) Function: Take the absolute value of the current data.
Usage: oracle is the same as mysql.
mysql: select abs(-1) value
oracle: select abs(-1) value from dual
3 ceil(-1.001)) ceiling(-1.001) Function: Return the smallest integer not less than X
Usage:
mysqls: select ceiling(-1.001) value
oracle: select ceil(-1.001) value from dual
4 floor(-1.001) floor(-1.001) Function: Return the largest integer value not greater than X
Usage:
mysql: select floor(-1.001) value
oracle: select floor(-1.001) value from dual
5 Max(expr)/Min(expr) Max(expr)/Min(expr) Function: Return the minimum or maximum value of expr. MIN() and MAX() can accept a string argument; in this
case, they will return the smallest or largest string passed down.
Usage:
ROACLE: select max(user_int_key) from t_usr;
MYSQL: select max(user_int_key) from t_usr;
6 character function ascii(str) ascii(str) Function: Return the ASCII code value of the leftmost character in the string str. If str is an empty string,
the return value is 0. If str is a NULL, the return value is also NULL.
Usage:
mysql:select ascii('a') value
oracle:select ascii('a') value from dual
7 CHAR(N,...) CHAR(N,...)
Function: CHAR() Interprets the parameter with an integer type, and returns a string composed of the characters given by the ASCII code value represented by the integer . NULL values ​​will be ignored.
Usage:
mysql:select char(97) value
oracle:select chr(97) value from dual
8 REPLACE(str,from_str,to_str) REPLACE(str,from_str,to_str) 功能: 在字符串 str 中所有出现的字符串 from_str 均被 to_str 替换,然后返回这个字符串.
用法:
mysql: SELECT REPLACE('abcdef', 'bcd', 'ijklmn') value
oracle: SELECT Replace('abcdef', 'bcd', 'ijklmn') value from dual
9 INSTR('sdsq','s',2) INSTR('sdsq','s') 参数个数不同
ORACLE: select INSTR('sdsq','s',2) value from dual(要求从位置2开始)
MYSQL: select INSTR('sdsq','s') value(从默认的位置1开始)
10 SUBSTR('abcd',2,2) substring('abcd',2,2) 函数名称不同:
ORACLE: select substr('abcd',2,2) value from dual
MYSQL: select substring('abcd',2,2) value
11 instr(‘abcdefg’,’ab’) locate(‘ab’,’abcdefg’) 函数名称不同:
instr -> locate(注意:locate的子串和总串的位置要互换)
ORACLE: SELECT instr('abcdefg', 'ab') VALUE FROM DUAL
MYSQL: SELECT locate('ab', 'abcdefg') VALUE
12 length(str) char_length() 函数名称不同:
ORACEL: SELECT length('AAAASDF') VALUE FROM DUAL
MYSQL: SELECT char_length('AAAASDF') VALUE
13 REPLACE('abcdef', 'bcd', 'ijklmn') REPLACE('abcdef', 'bcd', 'ijklmn') 一样:
ORACLE: SELECT REPLACE('abcdef', 'bcd', 'ijklmn') value from dual
MYSQL: SELECT REPLACE('abcdef', 'bcd', 'ijklmn') value
14 LPAD('abcd',14, '0') LPAD('abcd',14, '0') 一样:
ORACLE: select LPAD('abcd',14, '0') value from dual
MYSQL: select LPAD('abcd',14, '0') value from dual
15 UPPER(iv_user_id) UPPER(iv_user_id) 一样:
ORACLE: select UPPER(user_id) from t_usr;
MYSQL: select UPPER(user_id) from t_usr;
16 LOWER(iv_user_id) LOWER(iv_user_id) 一样:
ORACLE: select LOWER(user_id) from t_usr;
MYSQL: select LOWER(user_id) from t_usr;
17 控制函数 nvl(u.email_address, 10) IFNULL(u.email_address, 10)

ISNULL(u.email_address)
函数名称不同(根据不同的作用进行选择):
ORACLE: select u.email_address, nvl(u.email_address, 10) value from t_usr u (如果u.email_address=NULl,就在DB中用10替换其值)
MYSQL: select u.email_address, IFNULL(u.email_address, 10) value from t_usr u(如果u.email_address=NULl,显示结果中是10,而不是在DB中用10替换其值)
select u.email_address, ISNULL(u.email_address) value from t_usr u(如果u.email_address是NULL, 就显示1<true>,否则就显示0<false>)
18 DECODE(iv_sr_status,
 g_sr_status_com,
 ld_sys_date, NULL)
无,请用IF或CASE语句代替.
IF语句格式:(expr1,expr2,expr3)
说明:
1. decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)
该函数的含义如下:
IF 条件=值1 THEN
    RETURN(翻译值1)
ELSIF 条件=值2 THEN
    RETURN(翻译值2)
    ......
ELSIF 条件=值n THEN
    RETURN(翻译值n)
ELSE
    RETURN(缺省值)
END IF

2. mysql If语法说明
功能: 如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2;
否则返回值则为 expr3。IF() 的返回值为数字值或字符串值,具体情况视其所在
语境而定。
用法:
mysql: SELECT IF(1>2,2,3);
19 类型转换函数 TO_CHAR(SQLCODE) date_format/ time_format 函数名称不同
SQL> select to_char(sysdate,'yyyy-mm-dd') from dual;
SQL> select to_char(sysdate,'hh24-mi-ss') from dual;
mysql> select date_format(now(),'%Y-%m-%d');
mysql> select time_format(now(),'%H-%i-%S');
20 to_date(str,format) STR_TO_DATE(str,format) 函数名称不同:
ORACLE:SELECT to_date('2009-3-6','yyyy-mm-dd') VAULE FROM DUAL
MYSQL: SELECT STR_TO_DATE('2004-03-01', '%Y-%m-%d') VAULE
21 trunc(-1.002) cast(-1.002 as SIGNED) 函数名称不同:
TRUNC函数为指定元素而截去的日期值。
ORACLE: select trunc(-1.002) value from dual
MYSQL:select cast(-1.002 as SIGNED) value
MYSQL:
字符集转换 :   CONVERT(xxx  USING   gb2312)
类型转换和SQL Server一样,就是类型参数有点点不同  : CAST(xxx  AS   类型)  ,   CONVERT(xxx,类型),类型必须用下列的类型:
 
  可用的类型  
  二进制,同带binary前缀的效果 : BINARY  
  字符型,可带参数 : CHAR()   
  日期 : DATE   
  时间: TIME   
  日期时间型 : DATETIME   
  浮点数 : DECIMAL    
  整数 : SIGNED   
  无符号整数 : UNSIGNED  
22 TO_NUMBER(str) CAST("123" AS SIGNED INTEGER) 函数名称不同
ORACLE:SELECT TO_NUMBER('123') AS VALUE FROM DUAL;
MYSQL: SELECT CAST("123" AS SIGNED INTEGER) as value;
SIGNED INTEGER:带符号的整形
23 日期函数 SYSDATE now() / SYSDATE() 写法不同:
ORACLE:select SYSDATE value from dual
MYSQL:select now() value
select sysdate() value
24 Next_day(sysdate,7) 自定义一个函数:
F_COMMON_NEXT_DAY(
date,int)

函数名称不同:
ORACLE: SELECT Next_day(sysdate,7) value

FROM DUAL
MYSQL: SELECT F_COMMON_NEXT_DAY

(SYSDATE(), 3) value from DUAL;
(3:指星期的索引值)返回的指定的紧接着下一个星期的日期

25 ADD_MONTHS(sysdate, 2) DATE_ADD(sysdate(), interval 2 month) 函数名称不同:
ORACLE: SELECT ADD_MONTHS(sysdate, 2) as value from DUAL;
MYSQL: SELECT DATE_ADD(sysdate(), interval 2 month) as value from DUAL;
26 2个日期相减(D1-D2) DATEDIFF(date1,date2) 功能: 返回两个日期之间的天数。
用法:
mysql: SELECT DATEDIFF('2008-12-30','2008-12-29') AS DiffDate
oracle: 直接用两个日期相减(比如d1-d2=12.3)
27 SQL函数S SQLCODE MYSQL中没有对应的函数,但JAVA中SQLException。getErrorCode()函数可以获取错误号 Oracle内置函数SQLCODE和SQLERRM是特别用在OTHERS处理器中,分别用来返回Oracle的错误代码和错误消息。
MYSQL: 可以从JAVA中得到错误代码,错误状态和错误消息
28 SQLERRM MYSQL中没有对应的函数,但JAVA中SQLException。getMessage()函数可以获取错误消息 Oracle内置函数SQLCODE和SQLERRM是特别用在OTHERS处理器中,分别用来返回Oracle的错误代码和错误消息。
MYSQL: 可以从JAVA中得到错误代码,错误状态和错误消息
29

SEQ_BK_DTL_OPT_INT_KEY

.NEXTVAL

自动增长列 在MYSQL中是自动增长列. 如下方法获取最新ID:
  START TRANSACTION;   
    INSERT INTO user(username,password)
      VALUES (username,MD5(password));
    SELECT LAST_INSERT_ID() INTO id;
  COMMIT;
30 SUM(enable_flag) SUM(enable_flag) 一样:
ORCALE: SELECT SUM(enable_flag) FROM T_USR;
MYSQL: SELECT SUM(enable_flag) FROM T_USR;
31

DBMS_OUTPUT.PUT_LINE

(SQLCODE)

在MYSQL中无相应的方法,其作用是在控制台中打印,用于测试,对迁移无影响。 dbms_output.put_line每行只能显示255个字符,超过了就会报错

Oracle 替换为TiDB\达梦 函数细节描述

1、连接字符串在Oracle中用 ||, MySQL中用concat('%','b','%')

2、orcale 生成唯一序列是 select sys.guid() from dual ,mysql是 select uuid() from dual

3、mysql可以实现自增长主键(通过字段的auto_increment属性);Oracle则需要通过序列(Sequence)来实现。
4、mysql可以用双引号来引用字符串(当然单引号也行);Oracle只能用单引号。

5、mysql在查询语句中可以通过limit [offset,] <row count>来直接分页;而Oracle需要使用rownum。

7、mysql的查询时间可以使用 select sysdate(); ;而Oracle需要引用虚表(select sysdate from dual;)。
8、mysql对于like的查询,CONCAT('%', #{name,jdbcType=VARCHAR},'%') ;Oracle则是用LIKE '%'||#{name,jdbcType=VARCHAR}||'%' 
9、mysql中日期的转换用dateformat()函数;Oracle用to_date()与to_char()两个函数。

Oracle 替换为TiDB\达梦 Mapper 实操

Oracle 版本 Like 查询
<if test="vo.bankName != null and vo.bankName !=''">
    and bank_name like '%'||#{vo.bankName}||'%'
</if>

MySQL 版本  Like 查询
<if test="vo.bankName != null and vo.bankName !=''">
    and bank_name like concat('%',#{vo.bankName}, '%')
</if>
Oracle 版本之 判空函数NVl
<select id="***">
    select NVL(sum(1), 0) as total from t_user
</select>

MySQL 版本之 判空函数ifnull
<select id="***">
    select ifnull(sum(1), 0) as total from t_user
</select>
Oracle 版本之 分页rownum
select tt.* from (
    select ROWNUM AS r_n, t.* from(
     --业务逻辑表
    ) t where ROWNUM &lt;= #{vo.pageNum} + #{vo.pageSize}
    ) tt where tt.r_n &gt;= #{vo.pageNum}

MySQL 版本之 分页limit
select tt.* from (
    select t.* from(
     --业务逻辑表
    ) t limit #{vo.offset}, #{vo.pageSize}
    ) tt
Oracle 版本之 sysdate 函数

create_time = sysdate

Oracle 版本之 now() 函数

create_time = now()

对比Oracle和 TiDB\达梦(类MySQL) 函数缺失解决办法。

MySQL 创建F_COMMON_NEXT_DAY 函数, 类似Oracle  next_day()函数

create function F_COMMON_NEXT_DAY(dates DATE, day_of_week INT)
    RETURNS DATE
    DETERMINISTIC
    begin
        declare next_date DATE;
        set next_date = dates + interval day_of_week day;
        return next_date;
    end
# MySQL 自定义Next_day 函数使用
select F_COMMON_NEXT_DAY(now(), 2) from dual;

# 结果输出
2023-07-26

DOS 命令查询需要调整的Mapper 文件

```CMD
cd 切换至Mapper 所在文件夹目录
for /R %i in (*.xml) do @findstr /N /I /M "ifnull now()" "%i"
```

命令详解:

1、`cd 切换至Mapper 所在文件夹目录`: 转到指定的 Mapper文件夹。

2、`for /R %i in (*.xml)`:对 `切换至Mapper 所在文件夹目录` 文件夹及其所有子目录中的所有 `.xml` 文件进行循环,每次循环 `%i` 都会被替换为当前正在处理的文件的路径。

3. `do @findstr`:对每一个文件执行 `findstr` 命令。

4. `/N /I /M " ifnull now()"`:`findstr` 的选项,表示搜索时忽略大小写(`/I`),只有当整行匹配时才打印文件名(`/M`),并给出包含匹配内容的行号(`/N`)。

5. `"%i"`:该参数包含了当前正在处理的文件路径,`findstr` 就会在这个文件中搜索字符串 `ifnull` 或者`now()`。

知识点拓展

查询Oracle 关键函数字段推荐字符串

"substr instr length nvl decode to_char to_date trunc to_number sysdate next_day add_months rownum"

Guess you like

Origin blog.csdn.net/zhouzhiwengang/article/details/131891643