引言
在日益增长的大数据量时代下,基于业务场景不一致情况下数据存放的格式可谓是各式各样。除了需要在不同数据库间实现高效、实时的数据复制和同步。在数据同步过程中,数据转换和过滤的强大功能在一定程度上能解决很多的格式兼容性问题。Oracle的OGG软件除了是一款强大的数据同步工具,在几十年的发展下来,它本身也提供很多的工具、函数和接口来实现大部分场景的数据转换和过滤。相对而言国内的数据库生态的数据交互或同步工具发展比较晚,在这方面可以借鉴下GoldenGate的高效功能实现和丰富的支持方式。
本文将详细介绍Oracle GoldenGate软件实现数据转换和过滤的原理和方法,以帮助读者充分了解并掌握这一功能。针对于源端和目标不同或者异构数据库之间的数据,主要通过列映射、数据过滤和数据转换三大块以理论和实践的方式做重点的阐述,最后还介绍了宏、SQLEXEC和Tokens等高级的用法。
1 列映射
Colmap
使用MAP和TABLE参数的COLMAP
选项显式地将源列映射到具有不同名称的目标列,或者在源和目标名称相同时指定默认列映射。COLMAP
提供了选择、映射、转换和将数据从源列移动到目标列的说明。在COLMAP语句中,您可以使用任何Oracle GoldenGate列转换函数来转换映射列的数据。
在使用COLMAP时,如果表结构不同则需要创建一个数据定义文件(def),使用SOURCEDEFS
参数来标识定义文件。如果表具有相同的结构,并且将COLMAP用于转换等其他功能,则不需要源定义文件。你可以改用ASSUMETARGETDEFS
参数。
- EXTRACT进程中配置定义如下
TABLE <table spec>;
- REPLICAT进程中配置定义如下:
MAP <table spec>, TARGET <table spec>, COLMAP ([USEDEFAULTS, ] <target column> = <source expression>);
--比如如下为表结构不一致时
SOURCEDEFS ./dirdef/reference.def
MAP "SRC.TCUSTORD", TARGET "TRG.TCUSTORD",
COLMAP (USEDEFAULTS, &
CUST_CODE= @IF(@STREQ(@STRRTRIM(CUST_CODE),""),CUST_CODE,@STRRTRIM(CUST_CODE)), &
ORDER_DATA = @DATE("YYYY-MM-DD","YYYYMMDD",ORDER_DATE));
Colmatch
使用COLMATCH,可以在具有相同数据集的不同列名的结构类似的表之间进行映射。还可以配置全局列名前缀或后缀,使其被忽略。
- 比如,列名可以被显式映射:
COLMATCH NAMES CUST_CODE = CUST_ID
COLMATCH NAMES Customer_Code = "Cust_Code"
- 在GLOBAL文件中或者Extract/Replicat进程中配置
--所有的列映射都加前缀,例如列名NAME映射为NAME_SRC
COLMATCH SUFFIX _SRC
--所有的列映射都加前缀,例如列名NAME映射为SRC_NAME
COLMATCH PREFIX SRC_
Defgen工具
DEFGEN
实用程序为源或目标数据库模式中的表创建数据定义文件。它定义列结构、数据类型、字段长度和偏移量。DEFGEN最初是为异构环境设计的,它提供了一种在不同模式之间进行映射配置的简单方法。使用时,必须使用SOURCEDEFS
或TARGETDEFS
参数指定该文件。使用SOURCEDEFS
参数来标识目标系统上Replicat的定义文件,或者使用TARGETDEFS
参数来标识源系统或中间系统上Extract或Pump的定义文件。
配置GoldenGate使用数据定义文件包括以下主要步骤:
- 为DEFGEN工具创建一个参数文件
- 运行DEFGEN工具生成文件
- 配置GoldenGate进程引用定义文件
执行以下命令创建一个DEFGEN参数文件,并从GoldenGate Home,在Linux命令行defgen
上运行DEFGEN实用程序,创建scott.def文件。
$ cat > dirprm/scott.prm <<EOF
defsfile ./dirdef/scott.def
userid <user>@<DB_IP>/<SERVICE_NAME>, password <password>
table XXX.XXXXX;
table XXX.YYYYY;
EOF
$ ./defgen paramfile dirprm/scott.prm
...
2 数据过滤
用户过滤
如果你想忽略某个用户的所有操作,比如可以Oracle数据库使用OGG时做如下配置:
TRANLOGOPTIONS EXCLUDEUSER <user name>
DDL过滤
当启用DDL复制时,我们可以过滤DDL的子集。在下面的示例中,我们将让CREATE TABLE
和ALTER TABLE
添加或修改列语句。但是我们将过滤ADD约束或MODIFY约束语句。
DDL INCLUDE OPTYPE ALTER OBJTYPE 'table' INSTRWORDS 'modify'
INCLUDE OPTYPE CREATE OBJTYPE 'table'
INCLUDE OPTYPE ALTER OBJTYPE 'table' INSTRWORDS 'add'
EXCLUDE INSTRWORDS 'constraint'
DML过滤和转换
默认情况下,Oracle GoldenGate捕获并应用插入、更新和删除操作。
您可以在Extract或Replicat参数文件中使用以下参数来控制要处理的操作类型,例如只插入或只插入和更新。
IGNOREINSERTS | GETINSERTS
IGNOREUPDATES | GETUPDATES
IGNOREDELETES | GETDELETES
在遇到其他参数之前,该参数对所有后续的TABLE或MAP语句都有效。
可以在TABLE或MAP语句列表之前使用IGNOREUPDATES
, IGNOREINSERTS
和IGNOREDELETES
来过滤出相应的DML记录。GETUPDATES
、GETINSERTS
和GETDELETES
是默认值,它们必须在Extract或Replicat的参数文件中显式声明,以重置之前的配置。
GoldenGate除了提供以上的DML操作过滤外,同时还支持DML操作的转换。在Replicat参数文件中,可以使用以下参数将一种SQL操作转换为另一种:
- 使用
INSERTUPDATES
将源更新操作转换为插入目标表。这对于在该表上维护事务历史记录非常有用。事务日志记录要求不仅仅是更改的值,还得必须包含表中的所有列值。有些数据库不将完整的行值记录到它们的事务日志中,而只将更改的值记录到事务日志中。 - 使用
INSERTDELETES
将所有源删除操作转换为插入到目标表。这对于保留源数据库中曾经存在的所有记录的历史是有用的。 - 使用
UPDATEDELETES
将源删除转换为目标上的更新。
行过滤
基于需求通过简单的设置和复杂的定义都可以来实现数据行的定义。简单的过滤是通过TABLE (Extract)或MAP (Replicat)语句中的WHERE
子句实现的,而复杂的数据计算则使用FILTER
子句。
Where子句
配置WHERE子句很像SQL语句中的WHERE
子句。在本例中,我们将其添加到TABLE或MAP语句的末尾。下面的示例将从源跟踪中过滤出EMPLOYEES
表中那些SALARY大于100000的记录:
MAP HR.EMPLOYEES, TARGET HR.EMPLOYEES, WHERE (SALARY > 1000000);
另外,你可以在WHERE子句中使用函数@PRESENT
, @ABSENT
和@NULL
。这些是唯一与WHERE
子句兼容的GoldenGate函数。
@PRESENT
和@ABSENT
函数测试数据记录中是否存在列。@NULL
函数只测试数据中的空值。当与<>
(不等于)结合使用时,测试不为空。WHERE子句不能执行算术运算符,也不支持引用trail headers和用户token值和浮点数据类型。
如果源数据记录中存在SALARY列且不为空,则以下映射示例成功:
MAP HR.EMPLOYEES, TARGET HR.EMPLOYEES,WHERE (SALARY = @PRESENT AND SALARY <> @NULL);
在WHERE子句中添加@PRESENT
函数会导致当SALARY不存在时记录不会被丢弃。
MAP HR.EMPLOYEES, TARGET HR.EMPLOYEES, WHERE (SALARY = @PRESENT AND SALARY > 1000);
SQLPREDICATE带WHERE子句
SQLPREDICATE仅对TABLE
配置有用。使用SQLPREDICATE
在SELECT语句中包含一个常规的SQL WHERE子句,Extract在为初始加载从表中选择数据时使用这个子句。SQLPREDICATE强制选择返回的记录按照键值排序。
对于初始加载,SQLPREDICATE是一种比WHERE或FILTER选项更快的选择方法。它直接影响SQL语句,并且不需要Extract在过滤它们之前获取所有记录。对于Oracle表,SQLPREDICATE减少了存储在undo段中的数据量,这可以减少快照太旧错误的发生率。这在加载非常大的表时非常有用。
通过使用SQLPREDICATE
子句,您可以在两个或多个并行提取进程中对大型表的行进行分区。此配置还使您能够利用并行交付负载处理。SQLPREDICATE
还允许您根据时间戳或其他标准选择数据,以过滤提取并加载到目标表的行。SQLPREDICATE
可用于ORDER BY子句或任何其他类型的选择子句。
确保WHERE子句包含的列是键或索引的一部分。否则,Extract执行全表扫描,这会降低SELECT语句的效率。SQLPREDICATE适用于Oracle、DB2 LUW、DB2 on z/OS、DB2 for i和SQL Server数据库。不要对配置为同步事务更改的Extract组使用SQLPREDICATE。它只适用于初始加载Extract,因为它需要SELECT语句直接从表中选择记录。
语法如下
TABLE source_table, SQLPREDICATE 'WHERE where_clause';
--例如
TABLE hr.emp, SQLPREDICATE 'WHERE state = 'CO' and city = 'DENVER'';
TABLE U.XXX, SQLPREDICATE "WHERE order_type != '31' and not(order_type='30' and source_type='1') and req_type in('1000','1001','1002','1003','1004') ";
FILTER子句
相比于WHERE子句,FILTER除了支持行还可以支持列及所有OGG自带的内置转换函数。FILTER子句增加了一个额外的值,因为它允许对给定的DML操作和表计算行数据和列名。可以在“提取”和“复制”中使用。Filter子句的最大大小为5000字节。
使用上一节的示例:FILTER子句只允许在EMPLOYEES目标表上进行UPDATE或DELETE操作。它还将过滤SALARY大于1000的记录。
您可能更喜欢在EXTRACT处设置筛选器,仅为复制选择“更新和删除”。IGNORE
关键字提供与ON
相反的功能。
TABLE HR.EMPLOYEES, FILTER (ON UPDATE, ON DELETE, SALARY > 1000);
FILTER可以使用GoldenGate函数来提供复杂数据的比较和评估。
下面的例子演示了@STRFIND
函数,它在行数据中提供字符串比较,只选择EMPLOYEES表中FIRST_NAME列中有“JOHN”的记录:
TABLE HR.EMPLOYEES, FILTER (@STRFIND(FIRST_NAME , "JOHN") > 0);
还可以使用@COMPUTE
函数对FILTER执行计算。 下面的示例从CREDITCARD_ACCOUNT
表中选择余额超过10,000的数据记录:
TABLE SRC.CREDITCARD_ACCOUNTS, FILTER (@COMPUTE(CREDIT_LIMIT-CREDIT_BALANCE) > 10000);
可以为每个给定的TABLE或MAP表项指定多个FILTERS,这些过滤器会一直执行,直到有一个失败或全部通过。 可以使用@COLTEST
来检查表中是否有一条记录:
TABLE HR.EMPLOYEES,FILTER (@GETVAL (SALARY) > 1000 );
改变成如下
FILTER (@COLTEST (@GETVAL (SALARY), PRESENT);
或者检查是否没有找到
FILTER (@COLTEST (@GETVAL (SALARY), MISSING, NULL);
这个关于COST表的例子 如果UNIT_COST列缺失或无效,replicat赋值为0,否则将把UNIT_COST
值赋给目标列UNIT_PRICE
。
UNIT_PRICE = @IF (@COLTEST (UNIT_COST , MISSING, INVALID), 0, UNIT_COST)
如果FILTER子句为true,则FILTER RAISEERROR
选项创建一个用户定义的错误数:
MAP HR.EMPLOYEES, TARGET HR.EMPLOYEES,FILTER (ON UPDATE, ON DELETE, SALARY > 1000, RAISEERROR 9999 );
对于多字节字符集或字符集与本地操作系统不兼容的列,Oracle GoldenGate不支持FILTER。
@Range
所有GoldenGate函数在参数文件中都使用
“@”
前缀表示,并且总是在关键字之间输入空格。
还可以根据一系列值(如日期或数字)过滤数据。 @RANGE
函数可以用于增加大型和频繁访问的表的吞吐量,也可以用于将数据划分到不同的目的地,将任何表的行划分到两个或多个Oracle GoldenGate进程。它可以用于在TABLE或MAP语句的FILTER子句中指定每个范围。@RANGE
是安全的,可伸缩的。它通过保证相同的行总是由相同的处理组处理来保持数据完整性。这在概念上类似于Oracle用于表分区的Hash算法。
在以下示例中,根据源SALES
表的PROD_ID
列,复制工作负载被划分为三个范围(在三个Replicat进程之间):
(REPLICAT GROUP_1 PARAMETER FILE)
MAP SH.SALES, TARGET SH.SALES, FILTER ( @RANGE (1, 3, PROD_ID ));
(REPLICAT GROUP_2 PARAMETER FILE)
MAP SH.SALES, TARGET SH.SALES, FILTER ( @RANGE (2, 3,PROD_ID ));
(REPLICAT GROUP_3 PARAMETER FILE)
MAP SH.SALES, TARGET SH.SALES, FILTER ( @RANGE (3, 3, PROD_ID ));
当每个TABLE或MAP语句指定多个过滤器时,每个过滤器依次执行,直到有一个失败。任何筛选器的失败都会导致所有筛选器的失败。
@Case, @Eval,@ If
使用@IF
函数根据条件返回两个值中的一个。您可以将@IF
函数与其他Oracle GoldenGate函数一起使用,以开始一个条件参数,用于测试一个或多个异常条件。可以根据测试结果直接处理。如果需要,你可以嵌套@IF
语句:
--只有当AMT列大于0时,下面的语句才会返回一个数量;否则返回零。
AMOUNT_COL = @IF (AMT > 0, AMT, 0)
--如果STATE列是CA, AZ或NV,则返回WEST;否则返回EAST
MAP GSS.TCUSTMER, TARGET GSS.TCUSTMER_REPORT,
COLMAP ( USEDEFAULTS, COUNTRY_REGION = @IF (@VALONEOF (STATE, "CA", "AZ", "NV"), "WEST", "EAST"));
--如果`order_date`为00,则映射为强制日期,否则映射为order_date
MAP GSS.TCUSTORD, TARGET GGS.TCUSTORD,
COLMAP ( USEDEFAULTS,
ORDER_DATE = @IF ( @STRNCMP ( ORDER_DATE, "00",2 ) = 0, @DATE ("YYYY-MM-DD HH:MI:SS" , "YYYY-MM-DD HH:MI:SS", "2000-06-01 12:00:00"),ORDER_DATE));
--如果PRICE列和QUANTITY列都大于0,则下面的代码返回PRICE列乘以QUANTITY列的结果。
--否则,`@COLSTAT (NULL)`函数在目标列中创建一个NULL值。
ORDER_TOTAL = @IF (PRICE > 0 AND QUANTITY > 0, PRICE * QUANTITY, @COLSTAT (NULL))
使用@EVAL
函数根据一系列独立测试选择一个值。要指定的条件的数量没有限制。 在下面的示例中,如果AMOUNT列大于10000,则返回“high AMOUNT”。如果AMOUNT大于5000(小于或等于10000),则指定“somewhat high”和默认值,如果AMOUNT小于或等于5000,则返回“lower”的结果。
@EVAL (AMOUNT > 10000, "high amount", AMOUNT > 5000, "somewhat high", "lower")
使用@CASE
函数根据一系列值测试选择一个值。可以用@CASE
测试的用例数量没有限制。 如下例子,如果PRODUCT_ID是" CAR ",则返回" A car ",如果PRODUCT_CODE是" TRUCK ",则返回" A truck "。如果PRODUCT_CODE既不是" CAR "也不是" TRUCK ",函数返回" A vehicle "。
@CASE (PRODUCT_ID, "CAR", "A car", "TRUCK", "A truck", "A vehicle")
在以下示例中,我们将基于现有列的值将一个值放入给定列中。这条语句读作“如果COL_B
是23,设置COL_A
为14,否则如果COL_B
是24,设置COL_A
为15,在所有其他情况下,设置COL_A
为16”
MAP HR.TABLE1, TARGET HR.TABLE1,
COLMAP (USEDEFAULTS, COL_A = @CASE(COL_B,23,14,24,15,16));
列过滤
要控制源表中的哪些列被Oracle GoldenGate提取,请使用提取table参数的COLS
和COLSEXCEPT
选项。使用COLS
选择要提取的列,使用COLSEXCEPT
选择除COLSEXCEPT指定的列外的所有列。
当目标表不包含与源表相同的列,或者当列包含敏感信息(如个人识别码或其他专有业务信息)时,限制提取的列可能很有用。
以下参数只处理列:employee_id、email、department_id
TABLE hr.employees, COLS (employee_id ,email, department_id);
下面的参数处理除列salary和commission_pct之外的所有列。
TABLE hr.employees, COLSEXCEPT (salary and commission_pct);
注意:不要排除key列,也不要使用COLSEXCEPT排除包含不支持的数据类型的列。
3 数据转换
可以将源值操作为目标列的适当格式。OGG主要是通过内置函数函数使您能够操作数字和字符、执行测试、提取参数值、返回环境信息等操作来实现数据的转换。所有GoldenGate函数在参数文件中都以“@”
前缀表示。
检索日期和时间,对它们执行计算,并转换它们: @DATE, @DATEDIFF, @DATENOW
@DATENOW
函数可用于填充目标表上的MODIFIED_AT
列。GoldenGate的默认日期格式是YYYY-MM-DD HH:MI:SS
,由@DATENOW
函数生成。 @DATENOW
函数相当于Oracle数据库的SYSDATE
函数。
MAP HR.EMPLOYEES, TARGET HR.EMPLOYEES_REPORT,
COLMAP (USEDEFAULTS,
MODIFIED_AT = @DATENOW());
将二进制或字符串转换为数字 @NUMBIN
, @NUMSTR
转出来用字符串表示的。不要使用@NUMBIN
函数来映射token,这些是整数,不是二进制数据。
- 将字符串(字符)映射为数字。
- 在算术表达式中使用只包含数字的字符串列。
将数字转换为字符串@STRNUM
GoldenGate支持通过两个函数进行数值转换。@NUMSTR
函数将字符串转换为用于算术计算的数字。类似地,@STRNUM
将数字转换为字符串,但增加了填充字符的选项。下面的示例将把源表的CREDIT_BALANCE
值转换为一个字符串,用0填充,最多5个字符:
MAP HR.EMPLOYEES, TARGET HR.EMPLOYEES_REPORT,
COLMAP (USEDEFAULTS,
CREDIT_BALANCE = @STRNUM(CREDIT_BALANCE,RIGHTZERO, 5));
比较字符串:@STRCMP
, @STRNCMP
- 如果第一个字符串小于第二个字符串,则为-1。
- 如果两个字符串相等,则为0。
- 如果第一个字符串大于第二个字符串,则为1。
在事务类型上使用FILTER的extract参数的示例:
TABLE HR.EMPLOYEES, FILTER ( @STRCMP( @GETENV ("GGHEADER", "OPTYPE"), "INSERT") = 0 ));
--只过滤NAME="JOHN"的记录
`TABLE HR.EMPLOYEES, FILTER ( ON INSERT, ON UPDATE, ON DELETE, @STRCMP (NAME, "JOHN") = 0);
串接字符串:@STRCAT
, @STRNCAT
strca
t函数通过将两个或多个单独的字符串连接在一起来提供字符串连接。在下面的例子中,我们将源表的FIRST_NAME
和SURNAME
字段连接到目标表的ENAME
字段:
MAP HR.EMPLOYEES, TARGET HR.EMPLOYEES_REPORT,
COLMAP (USEDEFAULTS, ENAME = @STRCAT(FIRST_NAME," ",SURNAME));
从字符串中提取@STREXT,
@STRFIND
除了字符串操作之外,@subext
函数还用于字符串截断和字符提取。尽管该函数将根据开始和结束字符的位置从字符串中提取任何字符,但它适合将字符串截断为某个长度,如下面的示例所示。
该示例使用@STREXT
将字符串字段的部分提取到3个不同的列中。它使用源的PHONE_NUMBER中的第一个到第三个字符填充目标的AREA_CODE, PHONE_PREFIX使用字符4到6,PHONE_NUMBER使用字符7到10:
MAP HR.EMPLOYEES, TARGET HR.EMPLOYEES_REPORT,
COLMAP ( USEDEFAULTS,
AREA_CODE = @STREXT (phone_number, 1, 3),
PHONE_PREFIX = @STREXT (phone_number, 4, 6),
PHONE_NUMBER = @STREXT (phone_number, 7, 10) );
返回一个字符串的长度 @STRLEN
字符串替换 @STRSUB
@STRSUB
函数提供字符串替换,允许用一个新字符串替换一个字符模式。下面的例子将TITLE字段从源表转换为目标表的缩写形式:
MAP SRC.CREDITCARD_ACCOUNTS, TARGET TGT.CREDITCARD_ACCOUNTS,
COLMAP (USEDEFAULTS, TITLE = @STRSUB(TITLE, "DOCTOR","DR","MISTER","MR"));
大写转换:@STRUP
下面的例子说明了该函数的简单性:
MAP SRC.CREDITCARD_ACCOUNTS, TARGET TGT.CREDITCARD_ACCOUNTS,
COLMAP (USEDEFAULTS, &TITLE = @STRUP(TITLE));
COLSTAT -返回一个指示符,表示列是MISSING、NULL或INVALID
下面的例子将NULL返回到目标列JOB_ID:MAP HR.EXPLOYEES, TARGET HR.EMPLOYEES,COLMAP(USEDEFAULTS, job_id = @COLSTAT(NULL));
下面的@IF
计算使用@COLSTAT
返回NULL到目标列,如果价格和数量小于零: ORDER_TOTAL = PRICE * QUANTITY, @IF (PRICE < 0 AND QUANTITY < 0,@COLSTAT(NULL))
下面的代码将源BANK列与NULL进行比较,如果它为NULL,则目标列设置为NULL;否则,目标列将获得源LOANUM的值:LOANUM = @IF (@COLTEST (BANK, NULL), @COLSTAT(NULL), LOANUM)
4 其他技巧
宏Macro
使用宏来自动化多个参数语句的使用:
$ vi dirmac/macros.mac
macros.mac content:
macro #filter
begin
FILTER (ON UPDATE, ON DELETE, SALARY > 1000);
end;
$ vi dirprm/XXX.prm
INCLUDE <OGG_DIR>/macros.mac
TABLE HR.EMPLOYEES, #filter()
带参数的宏语句例子
--宏定义参数文件,用于range对应多个进程分发
$ vi dirprm/hmap.mac
MACRO #mapH1_parallel
PARAMS (#number,#parallels)
BEGIN
replacebadchar escape
spacestonull
map XXXX.ABC, target YYYY.ABC, filter(@range(#number,#parallels));
--comments
...
END;
--投递进程参数文件
$ vi dirprm/repa.prm
...
nolist
include ./dirprm/hmap.mac
list
#mapH1_parallel(1,5)
$ vi dirprm/repb.prm
...
#mapH1_parallel(2,5)
SQLEXEC
使用SQLEXEC
参数在Oracle GoldenGate处理的上下文中执行存储过程、查询或数据库命令。SQLEXEC使Oracle GoldenGate能够直接与数据库通信,以执行数据库支持的任何工作。这项工作可以是同步过程的一部分,例如为列转换检索值,也可以独立于提取或复制数据,例如执行在数据库中执行操作的存储过程。
SQLEXEC的工作原理有如下两种方式:
- 作为参数文件根级别的独立语句,用于执行SQL存储过程或查询或执行数据库命令。作为一个独立的语句,在Oracle GoldenGate处理过程中,SQLEXEC独立于TABLE或MAP语句执行。在独立的SQLEXEC参数中使用时,查询或过程不能包含参数。语法如下
SQLEXEC
{'call procedure_name()' | 'SQL_query' | 'database_command'}
[EVERY n {SECONDS | MINUTES | HOURS | DAYS}]
[ONEXIT]
[, THREADS (threadID[, threadID][, ...][, thread_range[, thread_range][, ...])]
- 作为TABLE或MAP参数的一部分,用于执行带或不带参数的存储过程或查询。当与参数一起使用时,执行的过程或查询可以接受来自源或目标行的输入参数,并传递输出参数。
--Oracle例子
--通过account中的account_code匹配lookup_table中的code_col列来获取desc_col列的值付给newacct的newacct_val
MAP sales.account, TARGET sales.newacct, &
SQLEXEC (ID lookup, &
QUERY 'select desc_col into desc_param from lookup_table &
where code_col = :code_param', &
PARAMS (code_param = account_code)), &
COLMAP (newacct_id = account_id, newacct_val = lookup.desc_param);
--DB2例子
--通过abc表的a列匹配uvw表的u列获取到uvw的v和w值,
--拿着v列值去匹配xyz表中的x列,得到y和z值
TABLE user.abc, TARGET user.cde, &
COLMAP(&
c=@getval(lookup1.c_W), d=@getval(lookup2.c_Y), e=@getval(lookup2.c_Z)
),&
SQLEXEC(ID lookup1, &
query 'select u c_U,v c_V,w c_W from user.UVW where u=?', &
params(p1 = A)
),&
SQLEXEC(ID lookup2, &
query 'select x C_X, y C_Y, z C_Z from user.XYZ where x=?', &
params(p1=@getval(lookup1.c_V)
)&
;
用户Tokens
用户令牌是信息数据,它被捕获并存储在GoldenGate记录头的用户令牌区域中,在用于复制的跟踪记录中。它们通常用于存储环境或系统信息,但值可以是任何值,甚至可以是从数据库列值计算出来的值。Token数据可以以多种方式检索和使用,以定制GoldenGate交付数据的方式。
要定义一个用户令牌并将其与数据关联,请使用Extract参数文件中TABLE参数的TOKENS
子句。它可以用来定义一个用户令牌,并使用@GETENV
函数将其与GoldenGate环境数据关联起来。
Syntax TABLE <table spec>, TOKENS (<token name> = <token data> [, ...]) ;
为存储在路径中的令牌键和值分配的总空间有限制。记录头中的标记区域允许最多2000字节的数据。令牌名称、数据长度以及数据本身必须适合该空间
命名令牌的最佳实践可以是使用与@getenv
调用相同的名称,并使用用户定义的前缀,如“TKN”。
例如,对于提交序列号(使用“getenv”类别“TRANSACTION”和键值“CSN”),令牌将被称为“TKN-TRANSACTION-CSN
”。
TABLE SRC.AUDIT,
TOKENS (TKN-OSUSER = @GETENV("GGENVIRONMENT","OSUSERNAME"),
TKN-TRANSACTION-CSN =@GETENV(“TRANSACTION”,”CSN”),
TKN-DBNAME = @GETENV ("DBENVIRONMENT","DBNAME"),
TKN-HOSTNAME = @GETENV ("GGENVIRONMENT","HOSTNAME"),
TKN-COMMITTIME = @GETENV("GGHEADER","COMMITTIMESTAMP"), TKN-REC-FILESEQNO=@GETENV ("RECORD", "FILESEQNO"),
TKN-REC-FILERBA=@GETENV ("RECORD", "FILERBA"));
@TOKEN
函数用于检索存储在GoldenGate记录头的用户令牌区域中的令牌数据。要在目标表中使用定义的令牌数据,请在Replicat MAP语句的COLMAP
子句中使用@TOKEN
列转换函数。@TOKEN
函数将标记的名称映射到目标列。Syntax @TOKEN (“<token name>”)
下面的MAP语句将目标列“osuser”、“transaction_csn”等映射到令牌“tk-osuser”、“tk-transaction-csn”等。
MAP SRC.AUDIT, TARGET TRG.AUDIT,
COLMAP (USEDEFAULTS,
OSUSER = @TOKEN("TKN-OSUSER"),
TRANSACTION_CSN = @TOKEN("TKN-TRANSACTION-CSN"),
DBNAME = @TOKEN("TKN-DBNAME"),
HOSTNAME = @TOKEN("TKN-HOSTNAME"),
COMMITTIME = @TOKEN("TKN-COMMITTIME"),
RECFILESEQNO = @TOKEN ("TKN-REC-FILESEQNO"),
REC-FILERBA = @TOKEN ("TKN-REC-FILERBA"));
作为一种替代方法,您可以在SQLEXEC
语句、GoldenGate宏或用户出口中使用@TOKEN
。
总结
通过本文的介绍,我们可以看到Oracle GoldenGate软件在数据同步中数据转换和过滤的重要性和灵活性。合理使用GoldenGate的转换和过滤功能,可以大大减少数据同步的复杂度,提高同步效率和精确度。除文中介绍的列映射、数据转换和过滤,OGG本身还提供指定方式实现类似审计的功能。同时,GoldenGate还支持实时同步和异构数据库间的数据复制,使得数据在不同数据库间能够高效地传输和共享。无论是企业级应用还是个人开发者,都可以通过学习和掌握GoldenGate的数据转换和过滤功能,为数据同步和数据集成提供更加可靠和稳定的解决方案。期望本文对读者在理解和应用GoldenGate的数据同步功能方面有所帮助,鼓励大家深入研究和探索GoldenGate在实际项目中的应用。
参考资料
- Oracle GoldenGate参考 21c 之 列转换函数
- 用于过滤和转换数据的Oracle GoldenGate的主要说明 (Doc ID 1450495.1)
- Reference for Oracle GoldenGate 21.3
- Reference for Oracle GoldenGate 21.3 - SQLEXEC
- Reference for Oracle GoldenGate 21.3 - MACRO