映射和转换数据
了解用于在源表和目标表之间集成数据的任务、函数、命令和流程。
控制映射和数据集成的参数
通过使用 TABLE 和 MAP 参数的一个或多个选项,可以完成 Oracle GoldenGate 执行的所有数据选择、映射和操作。
-
在提取参数文件中使用
TABLE。 -
在 Replicat 参数文件中使用
MAP。
TABLE 和 MAP 指定受参数文件中的其他参数影响的数据库对象。有关在这些参数中指定对象名称的说明,请参见 Specifying Object Names in Oracle GoldenGate Input 。
不同数据库之间的映射
具有不同数据结构的表之间的映射和转换需要源定义文件、目标定义文件,或者在某些情况下需要两者。不同数据库之间的映射由自描述线索控制,映射按列名完成,而不考虑源列或目标列的数据类型。
如果您不希望基于自描述线索的自动映射,或者希望向后兼容,则可以使用 SOURCEDEFS 或 TARGETDEFS。
NonStop 系统上的映射和转换
如果要将数据从 Windows 或 UNIX 系统映射或转换到 NonStop Enscribe 目标,必须在 Windows 或 UNIX 源系统上执行映射或转换。NonStop 的复制不能将三部分或两部分 SQL 表名称和数据类型转换为用于 Enscribe 平台的三部分文件名。Extract 可以使用 Enscribe 名称和目标数据类型设置线索数据的格式。
在 Windows 和 UNIX 系统上映射和转换
当 Oracle GoldenGate 仅在基于 Windows 和 UNIX 的系统上运行时,列映射和转换可以在提取进程或复制进程中执行。要防止在“提取”处理中增加此处理的间接费用,可以配置要在“复制”处理或中介系统上执行的映射和转换。
如果存在多个源和一个目标,则对源执行映射和转换可能更高效。
映射数据时的全球化注意事项
在计划在数据库和平台之间映射和转换数据时,请考虑 Oracle GoldenGate 在全球化方面支持或不支持的功能。
字符集之间的转换
如果源字符集和目标字符集不同,则 Oracle GoldenGate 会在它们之间进行转换,以便将对象名称和列数据进行比较、映射和正确地从一个数据库处理到另一个数据库。有关支持的字符集的列表,请参见 Supported Character Sets 。
为了确保从一个数据库到另一个数据库的字符表示准确,必须满足以下条件:
-
目标数据库的字符集必须是源数据库的超集或等效字符集。Equivalent 表示不相等,但具有相同的字符集。例如,Shift-JIS 和 EUC-JP 在技术上并不完全相同,但在大多数情况下具有相同的字符。
-
如果客户机应用程序使用不同的字符集,则数据库字符集也必须是客户机应用程序的字符集的超集或等效字符集。
-
在包括 Oracle 在内的许多数据库中,可以将字符强制转换为不属于字符集的数据库。Oracle GoldenGate 将此字符视为无效值,在复制数据时可能无法正确映射此字符。对于这些类型的情况,可以使用
REPLACEBADCHAR参数,如《 Parameters and Functions Reference for Oracle GoldenGate 》中所述。
在此配置中,每个字符在从客户机或源字符集转换为本地数据库字符集时表示。
复制进程可以支持从一个源字符集转换为一个目标字符集。
数据库对象名
Oracle GoldenGate 以其本机语言处理目录、方案、表和列名称,具体取决于源数据库和目标数据库的字符集编码。此支持将保留单字节和多字节名称、符号、重音字符以及区分大小写,并在数据库层次结构的各个级别考虑区域设置(如果可用)。
列数据
当数据包含在以下列类型中时,Oracle GoldenGate 支持在字符集之间转换列数据:
-
字符类型列:另一个字符集的
CHAR/VARCHAR/CLOB到CHAR/VARCHAR/CLOB;CHAR/VARCHAR/CLOB到NCHAR/NVARCHAR/NCLOB. -
包含基于字符串的数字和日期时间数据的列。在 z/OS EBCDIC 和非 z/OS ASCII 数据之间执行这些列的转换。此数据的 ASCII 和 ASCII 版本之间,以及 EBCDIC 和 EBCDIC 版本之间不会执行转换,因为在这些情况下数据是兼容的。
注:Oracle GoldenGate 支持从
0001-01-03 00:00:00到9999-12-31 23:59:59的时间戳数据。如果时间戳从 GMT 转换为本地时间,则这些限制也适用于生成的时间戳。不支持零月、零日字段或全部零日期值。例如,不支持 0000-00-00 00:00:00 等值,或者不支持包含零月或零日字段的任何日期值。
列数据的字符集转换仅限于源列的直接映射和复制 MAP 参数的 COLMAP 或 USEDEFAULTS 子句中的目标列。直接映射是名称到名称映射,不使用存储过程或列转换函数。Replicat 将执行字符集转换。提取不会执行转换。
区域设置保存
Oracle GoldenGate 在比较不区分大小写的对象名称时会考虑数据库的区域设置。有关支持的区域设置列表,请参见 Supported Locales 。
支持转义序列
Oracle GoldenGate 支持使用转义序列来表示参数文件中的字符串列、文字文本或对象名称。如果操作系统不支持所需的字符(如控制字符),或者用于需要不能在参数文件中使用的字符的任何其他目的,则可以使用转义序列。
转义序列可以在参数文件中的任何位置使用,但在 TABLE 或 MAP 语句中的以下元素中特别有用:
-
对象名称
-
WHERE子句 -
COLMAP子句,用于将 Unicode 字符分配给 Unicode 列,或将本机编码的字符分配给列。 -
COLMAP子句中的 Oracle GoldenGate 列转换函数。
Oracle GoldenGate 支持以下类型的转义序列:
-
\uFFFFUnicode 转义序列。任何UNICODE代码点都可以使用,代理对除外。 -
\377八进制转义序列 -
\xFF十六进制转义序列
应用下列规则:
-
如果用于映射
TABLE或MAP中的对象名称,则不应用任何限制。例如,以下TABLE规范有效:TABLE schema."\u3000ABC"; -
如果与列映射函数一起使用,则可以对任何代码点使用,但只能对
NCHAR/NVARCHAR列使用。对于CHAR/VARCHAR列,代码点限制为等效的 7 位 ASCII。 -
源数据类型和目标数据类型必须相同(例如,
NCHAR到NCHAR)。 -
每个转义序列以反向实体(代码点
U+005C)开头,后跟字符代码点。(solidus 通常称为反斜杠符号。)在参数语句或列转换函数的输入字符串中使用转义序列(而不是实际字符)。注:要指定参数文件中的实际反斜杠,请指定双反斜杠。例如,以下命令可在
COL1: @STRFIND (COL1, '\' )中找到反斜杠。
使用 \uFFFF Unicode 转义序列
-
\uFFFFUnicode 转义序列必须以小写u开头,后跟正好四个十六进制数字。 -
支持的范围如下:
-
0到9(U+0030到U+0039) -
A到F(U+0041到U+0046) -
a到f(U+0061到U+0066)
-
\u20ac 是欧元货币符号的 Unicode 转义序列。
注:要获得可靠的跨平台支持,请使用 Unicode 转义序列。八进制和十六进制转义序列没有在不同的操作系统上标准化。
使用 \377 Octal Escape 序列
-
必须仅包含三个八进制数字。
-
支持的范围:
-
第一个数字的范围是
0到3(U+0030到U+0033) -
第二位和第三位数字的范围是
0到7(U+0030到U+0037)
\200是 Microsoft Windows 上的欧元货币符号的八进制转义序列 -
使用 \xFF 十六进制转义方程
-
必须以小写
x开头,后跟正好两个十六进制数字。 -
支持的范围:
-
0到9(U+0030到U+0039) -
A到F(U+0041到U+0046) -
a到f(U+0061到U+0066)
-
\x80 是 Microsoft Windows 1252 Latin1 代码页上的欧元货币符号的十六进制转义序列。
使用 TABLE 和 MAP 映射列
Oracle GoldenGate 提供了表级别和全局级别的列映射。如果没有显式列映射规则,也会提供默认列映射。
本节包含以下用于映射列的准则:
列名中支持大小写和特殊字符
默认情况下,Oracle GoldenGate 遵循 SQL-92 规则来指定列名和文字。在 Oracle GoldenGate 参数文件、转换函数、用户出口和命令中,如果数据库需要双引号来强制区分大小写,则必须将区分大小写的列名括在双引号内。对于不需要引号的其他区分大小写的数据库,必须指定区分大小写的列名,因为它们存储在数据库中。文字必须用单引号引起来。有关更多信息,请参见 Differentiating Case-Sensitive Column Names from Literals 。
使用 COLMAP 配置表级列映射
如果您使用的是自描述线索,则源对象上的任何列都会映射到目标对象上的相同列名。您只需管理在源和目标之间不同的列名,或者需要转换列。
但是,如果不使用自描述线索,则默认映射是按列顺序而非列名完成的。因此,源的第 1 列将映射到目标的第 1 列,第 2 列将映射到第 2 列,依此类推。
使用 MAP 和 TABLE 参数的 COLMAP 选项可以:
-
将各个源列映射到具有不同名称的目标列。
-
在不需要显式列映射时指定默认列映射。
-
提供有关选择、映射、转换数据以及将数据从源列移动到目标列的说明。
使用 USEDEFAULTS 启用默认列映射
可以使用 COLMAP 的 USEDEFAULTS 选项为具有相同名称的任何对应源列和目标列指定自动默认列映射。USEDEFAULTS 可以消除显式映射每个目标列的需要,从而节省时间。
默认映射会导致 Oracle GoldenGate 映射这些列,如果需要,还可以根据数据定义文件转换数据类型。请勿为已使用显式映射语句映射的列指定默认映射。
以下列映射示例说明了对源表 ACCTBL 和目标表 ACCTTAB 使用默认和显式列映射。除以下差异外,这两个表中的大多数列都是相同的:
-
源表具有
CUST_NAME列,而目标表具有NAME列。 -
源表中的十位
PHONE_NO列对应于目标表中的独立AREA_CODE、PHONE_PREFIX和PHONE_NUMBER列。 -
源表中的
YY, MM和DD列分别对应于目标表中的单个TRANSACTION_DATE列。
为了解决这些差异,USEDEFAULTS 用于自动映射相似的列,而显式映射和转换函数用于不同的列。
以下示例显示了使用 MAP 和 TABLE 参数的 COLMAP 选项的列映射。它描述了源表 ACCTBL 到目标表 ACCTTAB 的映射。
MAP SALES.ACCTBL, TARGET SALES.ACCTTAB,
COLMAP ( USEDEFAULTS,
NAME = CUST_NAME,
TRANSACTION_DATE = @DATE ('YYYY-MM-DD', 'YY',YEAR, 'MM', MONTH, 'DD', DAY),
AREA_CODE = @STREXT (PHONE_NO, 1, 3),
PHONE_PREFIX = @STREXT (PHONE_NO, 4, 6),
PHONE_NUMBER = @STREXT (PHONE_NO, 7, 10)
)
;
表 3 示例列映射
| 参数语句 | 说明 |
|---|---|
COLMAP |
开始 COLMAP 语句。 |
USEDEFAULTS, |
当目标列名称相同时,按原样映射源列。 |
NAME = CUST_NAME, |
将源列 CUST_NAME 映射到目标列 NAME。 |
TRANSACTION_DATE = @DATE ('YYYY-MM-DD', 'YY', YEAR, 'MM', MONTH, 'DD', DAY), |
使用 @DATE 列转换函数将事务处理日期从源日期列转换为目标列 TRANSACTION_DATE。 |
AREA_CODE = @STREXT (PHONE_NO, 1, 3), PHONE_PREFIX = @STREXT (PHONE_NO, 4, 6), PHONE_NUMBER = @STREXT (PHONE_NO, 7, 10)) ; |
使用 @STREXT 列转换函数将源列 PHONE_NO 转换为 AREA_CODE、PHONE_PREFIX 和 PHONE_NUMBER 的单独目标列。 |
有关 Oracle GoldenGate 后跟规则的更多信息,请参阅了解默认列映射。
指定要在 COLMAP 子句中映射的列
COLMAP 语法如下:
COLMAP ([USEDEFAULTS, ] target_column = source_expression)
在此语法中,target_column 是目标列和 source_expression 的名称。source_expressions 的一些示例包括:
-
源列的名称,例如
ORD_DATE。 -
数字常量,例如
123。 -
用单引号括起的字符串常量,例如
'ABCD'。 -
使用 Oracle GoldenGate 列转换函数的表达式。在
COLMAP语句中,可以使用任何 Oracle GoldenGate 列转换函数转换映射列的数据,例如:@STREXT (COL1, 1, 3) -
下面是使用
BEFORE column_name的示例:BEFORE ORD_DATE -
下面是使用
AFTER column_name的示例:AFTER ORD_DATE。如果列出了列名,这是默认选项。
如果列映射涉及来自不同数据库类型的区分大小写的列,请指定存储在数据库中的每个列。
-
如果数据库需要双引号来强制实现区分大小写,请在双引号内指定区分大小写的列名。
-
如果数据库区分大小写而不要求加双引号,请指定存储在数据库中的列名。
下面显示了 Oracle AI Database 中的目标列与区分大小写的 SQL Server 数据库中的源列之间的映射。
COLMAP ("ColA" = ColA)
有关为 Oracle GoldenGate 指定名称的详细信息,请参阅在 Oracle GoldenGate 输入中指定对象名称。
有关映射具有不同字符集和区域设置的数据库中的源列和目标列时的全球化注意事项,请参见 Globalization Considerations when Mapping Data 。
避免使用 COLMAP 将值映射到键列(这会导致操作成为主键更新),Oracle GoldenGate 用于查找目标行的 WHERE 子句不会在键列图像之前使用正确的子句。相反,它将使用后面的图像。如果使用的是基于该键列的任何函数(例如 SQLEXEC 语句),将导致错误。
列映射限制
下面是列映射限制:
-
LOB列不能用于FILTER、WHERE列,也不能用作COLMAP语句中的source_expression。LOB列包括BLOB、CLOB、NCLOB、XMLType、用户定义的数据类型、嵌套表、VARRAYs和其他特殊数据类型。 -
如果源列包含超过 4000 个字节,则不能将其用于转换例程,因为该值作为
LOB记录存储在线索中。例如,Oracle 中的VARCHAR2(4000 CHAR) 和日语字符集存储为每个字符的 3 个字节。这意味着该列的长度可以为 12000 字节,Oracle GoldenGate 将此值存储为LOB字段。 -
Oracle GoldenGate 将执行的完整 SQL 语句大小将超过 4MB。例如,如果某个表包含数千个
VARCHAR2(4000)列,并且您希望每个列包含 4000 字节,则可能会导致 Oracle GoldenGate 将执行的 SQL 语句总数超过最大大小 4MB。
使用 COLMATCH 配置全局列映射
使用 COLMATCH 参数为列映射创建全局规则。使用 COLMATCH,可以在具有相同数据集的不同列名的类似结构表之间进行映射。与在单个 TABLE 或 MAP 语句中使用带有 COLMAP 子句的表级映射相比,COLMATCH 提供了一种更便捷的方式来映射此类型的列。
支持区分大小写,如下所示:
-
对于 MySQL,SQL Server(如果数据库区分大小写),
COLMATCH将查找完全匹配的大小写和名称,而不管是否以引号指定名称。 -
对于 Oracle AI Database 和 Db2 数据库,如果名称在同一数据库中区分大小写或不区分大小写,并且需要双引号才能显示区分大小写,则
COLMATCH需要在名称在数据库中用引号引起来时完全匹配大小写和名称。
语法
COLMATCH
{NAMES target_column = source_column |
PREFIX prefix |
SUFFIX suffix |
RESET}
| 参数 | 说明 |
|---|---|
NAMES target_column = source_column |
基于列名的映射。如果列名区分大小写,并且数据库需要使用引号来强制区分大小写,则应在列名两边添加双引号。对于这些数据库类型,Oracle GoldenGate 将未带引号的列名视为不区分大小写。对于支持区分大小写而不需要引号的数据库,请指定存储在数据库中的列名。如果 COLMATCH 位于不同数据库类型的列之间,请确保名称反映每个名称的适当大小写表示形式。例如,以下项在 Oracle AI Database 中指定区分大小写的目标列名 "aBc",在区分大小写的 SQL Server 数据库中指定区分大小写的源列名 aBc:COLMATCH NAMES "aBc" = aBc。 |
PREFIX prefix / SUFFIX suffix |
忽略指定的名称前缀或后缀。如果数据库需要引号来强制区分大小写,请用双引号将前缀或后缀括起来,例如 "P_"。对于这些数据库类型,将不带引号的前缀或后缀视为不区分大小写。对于支持区分大小写而不需要引号的数据库,请指定存储在数据库中的前缀或后缀。例如,"P_" 指定大写 P 前缀。以下示例指定要忽略的不区分大小写的前缀:COLMATCH PREFIX p_。目标列名 P_ABC 映射到源列名 ABC,目标列名 P_abc 映射到源列名 abc。以下示例指定要忽略的区分大小写的后缀:SUFFIX "_k"。目标列名 ABC_k 映射到源列名 ABC,目标列名 "abc_k" 映射到源列名 abc。 |
RESET |
为后续 TABLE 或 MAP 语句关闭以前定义的 COLMATCH 规则。 |
以下示例说明何时使用 COLMATCH. 源表和目标表相同,但表和列 names.The 数据库略有不同,不区分大小写。
| ACCT 表 | ORD 表 |
|---|---|
CUST_CODE CUST_NAME CUST_ADDR PHONE S_REP S_REPCODE |
CUST_CODE CUST_NAME ORDER_ID ORDER_AMT S_REP S_REPCODE |
| 账户表 | ORDER 表 |
|---|---|
CUSTOMER_CODE CUSTOMER_NAME CUSTOMER_ADDRESS PHONE REP REPCODE |
CUSTOMER_CODE CUSTOMER_NAME ORDER_ID ORDER_AMT REP REPCODE |
要将源列映射到此示例中的目标列,以及处理其他表的后续映射,语法如下:
COLMATCH NAMES CUSTOMER_CODE = CUST_CODE
COLMATCH NAMES CUSTOMER_NAME = CUST_NAME
COLMATCH NAMES CUSTOMER_ADDRESS = CUST_ADDR
COLMATCH PREFIX S_
MAP SALES.ACCT, TARGET SALES.ACCOUNT, COLMAP (USEDEFAULTS);
MAP SALE.ORD, TARGET SALES.ORDER, COLMAP (USEDEFAULTS);
COLMATCH RESET
MAP SALES.REG, TARGET SALE.REG;
MAP SALES.PRICE, TARGET SALES.PRICE;
根据示例中的规则,将出现以下情况:
-
数据从源
ACCT和ORD表中的CUST_CODE列映射到目标ACCOUNT和ORDER表中的CUSTOMER_CODE列。 -
将忽略
S_前缀。 -
具有相同名称的列(如
PHONE和ORDER_AMT列)将通过USEDEFAULTS自动映射,而无需显式规则。有关详细信息,请参阅了解默认列映射。 -
对于表
REG和PRICE,将关闭以前的全局列映射。这些表中的源列和目标列将自动映射,因为所有名称都是相同的。
了解默认列映射
对于自描述线索,如果显式列映射不存在(通过使用 COLMATCH 或 COLMAP),则默认情况下,Oracle GoldenGate 会根据以下规则映射源列和目标列。
如果使用的是 SOURCEDEFS 或 TARGETDEFS,则不适用。
-
如果找到名称和大小写与目标列完全匹配的源列,则会映射这两个列。
-
如果未找到大小写匹配项,则使用回退名称映射。回退映射执行不区分大小写的目标表映射以查找名称匹配。将使用大写名称应用不准确的列名匹配。此行为是由
GLOBALS参数NAMEMATCHIGNORECASE控制。您可以禁用与NAMEMATCHEXACT参数匹配的回退名称,也可以通过使用NAMEMATCHNOWARNING参数保持启用状态,但出现警告消息。 -
与任何源列都不对应的目标列采用由数据库确定的默认值。
如果无法执行默认映射,目标列将默认为下表中显示的值之一。
| 列类型 | 值 |
|---|---|
| 数值 | 零 (0) |
字符或 VARCHAR |
空格 |
| 日期或时间 | 当前日期和时间 |
可接受 NULL 值的列 |
空值 |
数据类型转换
了解 Oracle GoldenGate 如何映射数据类型。
数字栏位
将转换数字列以匹配目标列的类型和比例。如果目标列的小数位数小于源列的小数位数,则会在右侧截断数字。如果目标列的小数位数大于源列的小数位数,则会在右侧用零填充数字。
您可以使用 REPLACEBADNUM 参数为映射数字列时遇到的无效数字数据指定替代值。
字符类型列
字符类型列可以接受基于字符的数据类型,例如 VARCHAR、字符串表单中的数字、字符串表单中的日期和时间以及字符串文字。如果目标列的小数位数小于源列的小数位数,则会在右侧截断该列。如果目标列的比例大于源的比例,则会在该列右侧填充空格。
文字必须用单引号引起来。
通过使用 REPLACEBADCHAR 参数获取更多信息,映射字符列时,如果源或目标字符集不存在有效代码点,则可以控制 Oracle GoldenGate 进程的响应。
日期时间列
日期时间 (DATE、TIME 和 TIMESTAMP) 列可以接受日期时间和字符列以及字符串文字。文字必须用单引号引起来。要将字符列映射到日期时间列,请确保它符合 YYYY-MM-DD HH:MI:SS.FFFFFF. 的 Oracle GoldenGate 外部 SQL 格式
Oracle GoldenGate 支持从 0001-01-03 00:00:00 到 9999-12-31 23:59:59 的时间戳数据。如果时间戳从 GMT 转换为本地时间,则这些限制也适用于生成的时间戳。根据时区,转换可能会增加或减去小时数,这可能会导致时间戳超出支持的下限或上限。
所需的精度因数据类型和目标平台而异。如果目标列的比例小于源的比例,则会在右侧截断数据。如果目标列的比例大于源的比例,则使用当前日期和时间的值在右侧扩展该列。
选择和筛选行
只能对 Oracle GoldenGate 可用的列执行筛选。在 TRANLOG 提取中,Oracle GoldenGate 可以访问重做日志和数据库中存在的所有列。如果这些列不在重做日志中,则必须显式提取它们(使用 FETCHCOLS)才能对其进行筛选。在“提取”泵和“复制”中,列必须在线索文件中可用。因此,要在 FILTER 或 WHERE 子句中使用的任何列必须使用 ADD TRANDATA COLS 显式记录,并且必须保留 LOGALLSUPCOLS 的默认值。
要过滤掉或选择用于提取或复制的行,请使用 TABLE 和 MAP 参数的 FILTER 和 WHERE 子句。
FILTER 子句提供了比 WHERE 子句更多的功能,因为您可以采用任何 Oracle GoldenGate 列转换函数,而 WHERE 子句接受基本的 WHERE 运算符。
使用 FILTER 子句选择行
使用 FILTER 子句通过使用基本运算符或一个或多个 Oracle GoldenGate 列转换函数来基于数值选择行。
注:要基于字符串筛选列,请使用 Oracle GoldenGate 字符串函数之一或使用 WHERE 子句。
TABLE 语句中 FILTER 的语法如下所示:
TABLE source_table
, FILTER (
[, ON INSERT | ON UPDATE| ON DELETE]
[, IGNORE INSERT | IGNORE UPDATE | IGNORE DELETE]
, filter_clause);
MAP 语句中 FILTER 的语法如下所示,并包含错误处理选项。
MAP source_table, TARGET target_table,
, FILTER (
[, ON INSERT | ON UPDATE| ON DELETE]
[, IGNORE INSERT | IGNORE UPDATE | IGNORE DELETE]
[, RAISEERROR error_number]
, filter_clause);
有效的 FILTER 子句元素如下:
-
Oracle GoldenGate 列转换函数。这些函数内置在 Oracle GoldenGate 中,因此您可以执行测试、处理数据、检索值等。有关 Oracle GoldenGate 转换函数的详细信息,请参阅测试和转换数据。
-
数字
-
包含数字的列
-
返回数字的函数
-
算术运算符:
-
+(加号) -
-(减) -
*(乘) -
/(除) -
%(剩余)
-
-
对比运算符:
-
>(大于) -
>=(大于或等于) -
<(小于) -
<=(小于或等于) -
=(等于) -
<>(不等于) -
从比较派生的结果可以是零(表示
FALSE)或非零(表示TRUE)。
-
-
括号(用于对表达式中的结果进行分组)
-
连接运算符:
AND、OR
使用以下 FILTER 选项指定筛选器子句影响的 SQL 操作。这些选项都可以组合使用。
ON INSERT | ON UPDATE | ON DELETE IGNORE INSERT | IGNORE UPDATE | IGNORE DELETE
在 MAP 参数中使用 FILTER 的 RAISEERROR 选项可在过滤器失败时生成用户定义的错误。当需要触发事件以响应故障时,此选项很有用。
在 FILTER 子句中使用 @RANGE 函数可在多个 MAP 或 TABLE 语句之间分配处理工作量。
下面是一个示例:
REPERROR (9999, EXCEPTION)
MAP OWNER.SRCTAB, TARGET OWNER.TARGTAB,
SQLEXEC (ID CHECK, ON UPDATE, QUERY ' SELECT COUNT FROM TARGTAB WHERE PKCOL = :P1 ', PARAMS (P1 = PKCOL)),
FILTER (BALANCE > 15000),
FILTER (ON UPDATE, @BEFORE (COUNT) = CHECK.COUNT)
;
MAP OWNER.SRCTAB, TARGET OWNER.TARGEXC,
EXCEPTIONSONLY,
COLMAP ( USEDEFAULTS,
ERRTYPE = 'UPDATE FILTER FAILED'
)
;
表 4 使用多个 FILTER 语句
| 参数文件名 | 说明 |
|---|---|
REPERROR (9999, EXCEPTION) |
引发指定错误的异常错误。 |
MAP OWNER.SRCTAB, TARGET OWNER.TARGTAB, |
启动 MAP 语句。 |
SQLEXEC (ID CHECK, ON UPDATE, QUERY ' SELECT COUNT FROM TARGTAB ' 'WHERE PKCOL = :P1 ', PARAMS (P1 = PKCOL)), |
每当遇到更新时,执行查询以检索 COUNT 列的当前值。此外,还有一个 BEFOREFILTER 选项,允许在处理 FILTER 子句之前执行查询或存储过程。这允许在运行时在 FILTER 内使用 SQLEXEC 部分中的值。 |
FILTER (BALANCE > 15000), |
使用 FILTER 子句选择余额大于 15000 的行。 |
FILTER (ON UPDATE, @BEFORE (COUNT) = CHECK.COUNT) |
在应用目标更新之前,使用另一个 FILTER 子句确保源 COUNT 列的值与目标列中的值匹配。 |
; |
分号将结束 MAP 语句。 |
MAP OWNER.SRCTAB, TARGET OWNER.TARGEXC, EXCEPTIONSONLY, COLMAP (USEDEFAULTS, ERRTYPE = 'UPDATE FILTER FAILED'); |
指定异常错误 MAP 语句。错误 9999 的 REPERROR 子句可确保将执行映射到 TARGEXC 的异常错误。 |
示例 9-5 调用 @COMPUTE 函数
以下示例调用 @COMPUTE 函数以提取价格乘以金额超过 10,000 的记录。
MAP SALES.TCUSTORD, TARGET SALES.TORD,
FILTER (@COMPUTE (PRODUCT_PRICE * PRODUCT_AMOUNT) > 10000);
示例 9-6 调用 @STREQ 函数
下面使用 @STREQ 函数提取字符列值为 'JOE'. 的记录
TABLE ACCT.TCUSTORD, FILTER (@STREQ ("Name", 'joe') > 0);
示例 9-7 选择记录
下面将选择 AMOUNT 列大于 50 的记录,并对 UPDATE 和 DELETE 操作执行过滤器。
TABLE ACT.TCUSTORD, FILTER (ON UPDATE, ON DELETE, AMOUNT > 50);
示例 9-8 使用 @RANGE 函数
(复制组 1 参数文件)
MAP sales.acct, TARGET sales.acct, FILTER (@RANGE (1, 2, ID));
(复制组 2 参数文件)
MAP sales.acct, TARGET sales.acct, FILTER (@RANGE (2, 2, ID));
可以在一个 MAP 或 TABLE 语句中组合多个 FILTER 子句,如 Table 9-4 中所示,该表显示了 Replicat 参数文件的一部分。Oracle GoldenGate 按列出的顺序执行过滤器,直到一个过滤器失败或所有过滤器都通过为止。如果一个过滤器失败,它们都会失败。
使用 WHERE 子句选择行
使用 WHERE 子句中的表 9-5 中的任何元素可基于条件语句选择或排除行(或两者)。每个 WHERE 子句必须用括号括起来。文字必须用单引号引起来。
表 5 允许的 WHERE 运算符
| 元素 | 示例 |
|---|---|
| 列名 | PRODUCT_AMT |
| 数值 | -123, 5500.123 |
| 文字串 | 'AUTO', 'Ca' |
| 内置列测试 | @NULL、@PRESENT、@ABSENT(该行中的列为空、存在或缺失)。这些测试内置在 Oracle GoldenGate 中。请参见 Considerations for Selecting Rows with FILTER and WHERE 。 |
| 比较操作符 | =, <>, >, <, >=, <= |
| 联合运算符 | AND, OR |
| 分组括号 | 使用左括号和右括号 ( ) 对多个元素进行逻辑分组。 |
对于具有多字节字符集或与本地操作系统的字符集不兼容的字符集的列,Oracle GoldenGate 不支持 FILTER。
WHERE 不支持算术运算符和浮点数据类型。要使用更复杂的选择条件,请使用 FILTER 子句或用户出口例程。
WHERE 的语法在 TABLE 和 MAP 语句中是相同的:
TABLE table, WHERE (clause);
MAP source_table, TARGET target_table, WHERE (clause);
使用 FILTER 和 WHERE 选择行的注意事项
以下建议可帮助您创建成功的选择子句。注:本节中的示例假定数据库不区分大小写。
确保筛选器的数据可用性
如果数据库仅将 changed 列的值记录到事务日志中,则如果选择标准引用了任何未更改的列,则可能会出现错误。Oracle GoldenGate 会忽略此类行操作,将它们输出到放弃文件中,并发出警告。
为避免缺少列错误,请按如下方式创建选择条件:
-
如果可能,仅使用主键列作为选择条件。
-
通过为这些列启用补充日志记录,使所需的列值可用。或者,可以使用
TABLE参数的FETCHCOLS或FETCHCOLSEXCEPT选项。这些选项对所有受支持的数据库有效。它们查询数据库以提取日志中不存在的值。要在执行FILTER或WHERE子句之前检索值,请将FETCHBEFOREFILTER选项包含在TABLE语句的FILTER或WHERE子句之前。例如:
TABLE DEMO.PEOPLE, FETCHBEFOREFILTER, FETCHCOLS (age), FILTER (age > 50);
- 首先测试列的存在性,然后测试列的值。要测试是否存在列,请使用以下语法。
column_name {= | <>} {@PRESENT | @ABSENT}
以下示例返回 amount 列超过 10,000 时的所有记录,并且不会导致在缺少 amount 时丢弃记录。
WHERE (amount = @PRESENT AND amount > 10000)
比较列值
要确保比较中使用的元素匹配,请比较相应的列类型:
-
字符串的字符列。
-
数字列到数字值,其中可以包含符号和小数点。
-
使用应用程序检索列的格式,将日期和时间列设置为文字字符串。
测试 NULL 值
要对 NULL 值的列求值,请使用以下语法。
column {= | <>} @NULL
如果列值为 NULL,则以下语句将返回 TRUE,从而复制该行。它为所有其他情况(包括记录中缺少的列)返回 FALSE。
WHERE (amount = @NULL)
以下命令仅当该列存在于记录中且不是 NULL 时才返回 TRUE。
WHERE (amount = @PRESENT AND amount <> @NULL)
注:如果线索中的值包含超过 4000 个字节,则 @NULL 函数将返回 TRUE。
检索前后值
对于更新和删除操作,检索源列的 BEFORE 值(发生更新之前的值)可能非常有用。对于插入,所有列值均视为 AFTER 图像。
这些值存储在线索中,可用于筛选器和列映射。例如:
-
在异常
MAP语句中检索列映射规范中的行之前图像,并将这些值映射到异常表,以用于测试或排除冲突解决例程。 -
执行差值计算。例如,如果表具有
Balance列,则可以通过从新余额中减去原始余额来计算特定事务处理的净结果,如下例所示:MAP "owner"."src", TARGET "owner"."targ", COLMAP (PK1 = PK1, delta = balance - @BEFORE (balance));注:上一个示例指示一个区分大小写的数据库,例如 Oracle。表名采用引号,以反映区分大小写。
引用之前值
-
将
@BEFORE列转换函数与需要其前置值的列的名称结合使用,如下所示:@BEFORE (column_name) -
使用“提取”参数文件中的
GETUPDATEBEFORES参数捕获事务处理记录中的图像之前,或在“复制”参数文件中使用该参数在列映射或筛选器中使用之前的图像。如果使用冲突解决和检测 (Conflict Resolution and Detection,CDR) 功能,则可以使用TABLE的GETBEFORECOLS选项。要使用这些参数,事务处理日志中必须存在所有列。如果数据库仅记录更改的列的值,则使用@BEFORE函数可能会导致“列缺失”条件,并执行列映射,就像该列不在记录中一样。请参见 Ensuring Data Availability for Filters 以确保列值可用。Oracle GoldenGate 还提供了
@AFTER函数,用于在筛选需要时检索值,以用于转换函数或其他用途。请参阅《 Parameters and Functions Reference for Oracle GoldenGate 》中的@BEFORE和@AFTER。
选择列
要控制 Oracle GoldenGate 提取源表的哪些列,请使用 TABLE 参数的 COLS 和 COLSEXCEPT 选项。使用 COLS 可选择要提取的列,使用 COLSEXCEPT 可选择除 COLSEXCEPT 指定的列之外的所有列。
当目标表不包含与源表相同的列,或者当列包含敏感信息(例如个人标识号或其他专有业务信息)时,限制提取的列会非常有用。
选择和转换 SQL 操作
默认情况下,Oracle GoldenGate 捕获并应用 INSERT、UPDATE 和 DELETE 操作。您可以使用提取或复制参数文件中的以下参数来控制处理哪种操作,例如仅插入或仅插入和更新。
GETINSERTS | IGNOREINSERTS
GETUPDATES | IGNOREUPDATES
GETDELETES | IGNOREDELETES
可以使用 Replicat 参数文件中的以下参数将一种类型的 SQL 操作转换为另一种类型:
-
使用
INSERTUPDATES将源更新操作转换为插入到目标表。这对于维护该表的事务处理历史记录非常有用。事务处理日志记录必须包含表的所有列值,而不仅仅是更改的值。某些数据库不会将整行值记录到其事务处理日志中,而仅记录已更改的值。 -
使用
INSERTDELETES将所有源删除操作转换为插入到目标表。这对于保留源数据库中曾经存在的所有记录的历史记录非常有用。 -
使用
UPDATEDELETES将源删除转换为目标上的更新。
使用事务处理历史记录
借助 Oracle GoldenGate,您可以保留对目标记录所做的更改的历史记录,并映射有关导致每次更改的操作的信息。此历史记录可用于创建基于事务处理的报告系统,该系统针对对表执行的每个操作包含单独的记录,而不是仅包含每个记录的最新版本。
例如,对名为 CUSTOMER 的目标表执行的以下系列操作不会留下对 ID Dave 的跟踪。最后一次操作会删除该记录,因此无法找出 Dave 的帐户历史记录或其期末余额。
表 6:表 CUSTOMER 的工序历史记录
| 序列 | 操作 | ID | BALANCE |
|---|---|---|---|
1 |
Insert |
Dave |
1000 |
2 |
Update |
Dave |
900 |
3 |
Update |
Dave |
1250 |
4 |
Delete |
Dave |
1250 |
将此历史记录保留为一系列记录在许多方面都很有用。例如,可以生成事务处理的净影响。
实施事务处理报告
-
要准备提取以在值之前捕获,请使用提取参数文件中的
GETUPDATEBEFORES参数。之前的值(或之前图像)是执行更新之前列的现有值。使用映像之前,Oracle GoldenGate 可以创建事务处理记录。 -
要使 Replicat 准备以插入形式发布所有操作,请使用 Replicat 参数文件中的
INSERTALLRECORDS参数。对表的每个操作都将成为该表中的新记录。 -
要映射事务处理历史记录,请使用
@GETENV列转换函数的GGHEADER选项的返回值。在TABLE或MAP参数的COLMAP语句中包括转换函数作为源表达式。
使用表 9-6 中显示的事务样例系列,可以创建以下参数配置,以生成面向事务的客户视图,而不是数据库的最新状态。
| 流程 | 参数语句 |
|---|---|
| 提取 | GETUPDATEBEFORES TABLE ACCOUNT.CUSTOMER; |
| 复制 | INSERTALLRECORDS MAP SALES.CUSTOMER, TARGET SALES.CUSTHIST, COLMAP (TS = @GETENV ('GGHEADER', 'COMMITTIMESTAMP'), BEFORE_AFTER = @GETENV ('GGHEADER', 'BEFOREAFTERINDICATOR'), OP_TYPE = @GETENV ('GGHEADER', 'OPTYPE'), ID = ID, BALANCE = BALANCE); |
注:这不代表 Oracle GoldenGate 进程的完整参数文件。另请注意,这些示例表示不区分大小写的数据库。
此配置可以进行如下查询,这些查询返回每个事务处理的净总和以及事务处理的时间和客户 ID。
SELECT AFTER.ID, AFTER.TS, AFTER.BALANCE - BEFORE.BALANCE
FROM CUSTHIST AFTER, CUSTHIST BEFORE
WHERE AFTER.ID = BEFORE.ID AND AFTER.TS = BEFORE.TS AND
AFTER.BEFORE_AFTER = 'A' AND BEFORE.BEFORE_AFTER = 'B';