---
title: ETL 概要-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于 ETL 概要相关的常见问题和使用技巧，帮助您快速解决 ETL 概要的难题。
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

划线反馈

# ETL 概要

更新时间：2023-12-19 09:16

适用版本： V4.2.x、V4.1.x、V4.0.x、V3.4.x、V3.3.x、V3.2.2 内容类型：TechNote  

本文为您介绍 OceanBase 迁移服务（OceanBase Migration Service，OMS）支持的 ETL 的使用范围和限制。

## 适用版本

适用于 OMS V3.2.2 及之后版本。

## 实现原理

OMS 的 ETL 使用了 MySQL 的语法作为输入语法，目前仅支持过滤数据，用户只需要填入过滤数据的条件就可以对全量和增量进行数据过滤。

用户填入的过滤条件会被解析成为由算子组成的语法树。每条记录都会被该语法树中的算子进行计算然后决定是否过滤。

目前支持的运算符如下。

```markdown
expr 表示算子, [|] 表示正则匹配中选取其中的一个的含义。
一元算子：
    针对整形
        +expr, -erpr, ~expr, !expr
    针对布尔类型
        expr NOT TRUE, expr IS TRUE
    针对空值比较
        expr IS NULL, expr IS NOT NULL
二元算子：
    针对布尔类型
        expr [AND | OR | XOR] expr
    基于整形的算术运算
        expr [ & | >> | << | + | - | * | / | % | ^] expr
        expr | expr
    基于值比较的运算
        expr [> | >= | < | <= | = | != | <>] expr
基于布尔值的判定：
    BETWEEN expr AND expr
    IN (expr, ...., expr)
函数（自定义函数）:
    CONCAT（expr1, expr2）
        IF expr1 == NULL, RETURN expr2
        ELSE IF expr2 == null, RETURN expr1
        ELSE RETURN expr1 + expr2
        也就是如果 expr1 和 expr2 都是 NULL 是会返回 NULL 的。
        否则返回非 NULL 的一方或者两方的 CONCAT 值
    SUBSTR（expr, exprS （,exprC）?）
        SUBSTR（expr, exprS （,exprC）?） 行为等同于数据库的 SUBSTRING 函数
        字符串的索引下标从 1 开始, exprS 是开始拷贝字符串的位置, exprC 是拷贝字符串的数目
        如果 exprC <= 0 或者 exprS == 0 会返回空串
        str = '1234567';
        如果 exprS > 0 并且 exprS <= str.length, 那么返回的字符串为
            SUBSTRING（str, 1, 2） = '12'
            SUBSTRING（str, 1） = '1234567'
            SUBSTRING（str, 6, 3） = '67'
            SUBSTRING（str, 7, 2） = '7'
        如果 exprS > str.length那么返回空串
            SUBSTRING（str, 8, 2） = ''
        如果 exprS < 0, 并且 -exprS <= str.length, 那么开始位置为 str.length + exprS
            SUBSTRING（str, -1, 2） = '7'
            SUBSTRING（str, -4, 2） = '45'
            SUBSTRING（str, -4） = '4567'
        如果 exprS < 0, 并且 -exprS > str.length, 返回空串
    REPLACE（exprO, expr1, expr2）
        如果 exprO 为 null 返回 null
        如果 expr1 为 null 返回 exprO
        如果 expr2 为 null，等同于 REPLACE（exprO, expr1, ""） 或者 REMOVE（exprO, expr1）

```

### 注意事项

- 不支持类型

  不支持 DOUBLE/FLOAT 浮点型数值计算比较，这样可能会造成结果的错误。
 - 关于 NULL 的比较

  任何与 NULL 的比较，包括 =, >=, <=, !=, >, < 等都是 FALSE, NULL = NULL 也是 FALSE。

  如果要比较 NULL 值应该使用 IS NULL 或者 IS NOT NULL。
 - 关于 CHAR 类型字符串的比较

  忽略右空格比较，'abc' = 'abc '。

  前置空格不忽略，' abc' != 'abc'。

  大小写不忽略，'abc' != 'ABC'。
 - 关于 VARCHAR 类型字符串比较

  MySQL 和 DB2 相关的 VARCHAR 比较忽略右空格, 'abc' = 'abc '。

  ORACLE VARCHAR 比较不忽略右空格, 'abc' != 'abc '。
 - AND 和 OR 的优先级

  对于没有括号约束的 AND 和 OR 运算符，AND 的优先级高于 OR 的优先级，请使用括号来指定优先级。
 - 列名转换

  ETL 不会对用户传入的列的名称进行任何的大小写的转换，请使用转义符 '`' 来转义列名称。
 - 隐式转换

  使用 CAST(expr AS type) 进行显式的类型转换，目前支持的类型转换包括：

  type = CHARACTER/CHAR 到 VARCHAR_STRING 转换。

  type = DEC/NUMERIC/DECIMAL 到 DECIMAL 转换。

  type = DOUBLE 到 DOUBLE 转换。

  type = SIGNED/UNSIGNED 到 INT64 转换。

  type = DATE 到 DATE 转换。

  type = TIME 到 TIME 转换。

  type = DATETIME 到 DATETIME 转换。

  目前支持的隐式转换包括：

  INT64 和 DECIMAL 转换到 DECIMAL 比较。

  INT64 和 STRING 转换到 INT64 比较。

  DECIMAL 和 STRING 转换到 DECIMAL 比较。

  对于 MySQL 的 TIMSTAMP 类型可以使用 Linux 时间戳或者 'YYYY-MM-DD HH:MM:SS ZoneID'，如果ZoneID没有指定，那么会使用 +08:00 来转换时区。

  对于 ORACLE 的 TIMESTAMP WITH LOCAL TIMEZONE 可以使用 'YYYY-MM-DD HH:MM:SS ZoneID' 来进行比较，如果ZoneID没有指定，那么会使用 +08:00 来转换时区。

## 运行示例

```markdown
过滤条件： `id` > 100 AND `ts` < '2022-07-11 00:00:00 +08:00'。
INSERT/DELETE id = 1000, ts = '2022-07-10 00:00:00 +08:00' 通过。
INSERT/DELETE id = 99, ts = '2022-07-10 00:00:00 +08:00' 过滤。

UPDATE 更新前 id = 1000, ts = '2022-07-10 00:00:00 +08:00'。
       更新后 id = 1000, ts = '2022-07-10 00:00:00 +08:00' 通过。

UPDATE 更新前 id = 99, ts = '2022-07-10 00:00:00 +08:00'。。
       更新后 id = 99, ts = '2022-07-10 00:00:00 +08:00' 过滤。

UPDATE 更新前 id = 99, ts = '2022-07-10 00:00:00 +08:00'。
       更新后 id = 1000, ts = '2022-07-10 00:00:00 +08:00'。
       拆分为 INSERT  id = 1000, ts = '2022-07-10 00:00:00 +08:00'。

UPDATE 更新前 id = 1000, ts = '2022-07-10 00:00:00 +08:00'。
       更新后 id = 99, ts = '2022-07-10 00:00:00 +08:00'。
       拆分为 DELETE id = 1000, ts = '2022-07-10 00:00:00 +08:00'。

```

上一篇

[如何更新黑白名单](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000234456)

下一篇

[如何为 Oracle 至 OceanBase 数据库 Oracle 租户的数据迁移项目配置归档模式](https://www.oceanbase.com/knowledge-base/oceanbase-database-20000000105) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
