www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Migrating Your Oracle Database to
AWS with Minimal Downtime
Suzanne Strasser, Return Path, Inc.
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
About Me
• Senior database administrator at Return Path
• Worked with Oracle since 1994
• Areas of expertise – Database performance tuning and monitoring
– Replication
• Past presenter: – RMOUG Training Days, Collaborate
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
About Return Path
• Global leader in email intelligence
• Specialize in analysis of email data
• Provider of industry-leading email intelligence solutions – Ensure that only wanted emails reach the inbox
• Visit us at http://www.returnpath.com
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Agenda
• Oracle databases in AWS: RDS vs. EC2
• Migration methods: pros and cons
• Case study: replicating Oracle database to RDS – Configuring continuous replication
– Validation and testing
– Switchover steps
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Oracle AWS Databases: RDS vs EC2
• Pros and cons of: – Relational Database Service (RDS)
– Elastic Compute Cloud (EC2)
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Relational Database Service (RDS): Pros
• Easy to set up, operate, and scale
• Manages common DBA tasks for you – Backups, software patching, monitoring, hardware scaling, …
• High availability via Multi-AZ – Built-in automated failover to standby database
• Includes Oracle licenses in pricing (SE1 and SE2)
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Relational Database Service (RDS): Cons
• No support for many options: – Real Application Clusters (RAC)
– Data Guard / Active Data Guard
– Database Vault
– Automated Storage Management (ASM)
– Multitenant Database
– Java Support
– Unified Auditing
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
RDS: Cons (cont'd)
• No operating system-level or SYSDBA access
• Restricted access to some SYS procedures & tables
• Enterprise Edition requires BYOL
• Database size <= 16 TB
• Maximum IOPS <= 40,000
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Elastic Compute Cloud (EC2): Pros
• Most similar to running Oracle on your own servers – Command line and SYSDBA access
• Gives full control of the database
• All options for Enterprise Edition included
• No restrictions on max database size or IOPS
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Elastic Compute Cloud (EC2): Cons
• More work to set up, configure, and tune
• Requires self management of: – Database backups, point-in-time recoveries
– Standby databases
– Storage
– Security patches
– All Oracle version upgrades
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Migration Methods: Pros and Cons
• Database Migration Service (DMS)
• Oracle GoldenGate
• Oracle Streams
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
DMS Diagram
Oracle Source
Database
AWS Target
Database
DMS Replication
Instance
1. Start replication instance
2. Connect to source, target databases
3. Create task to select tables
4. DMS uses CDC to keep tables in sync
5. Switch applications over to target
6. Stop replication task (CDC)
Bulk load, then
Change Data Capture and Apply
Turn on
supplemental logging
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Database Migration Service (DMS): Pros
• Supports homogeneous and heterogeneous migrations – Oracle to Oracle
– Oracle to PostgreSQL, MySQL, …
• Change Data Capture technology
• Can migrate subsets of tables and data
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Database Migration Service (DMS): Cons
• Clobs are difficult and slow to migrate – “Limited LOB mode” for clobs > 64kb
– “Full LOB mode” runs very slow
• 4-byte UTF-8 characters not supported
• Not as flexible as Streams
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
GoldenGate Diagram
1. Configure GoldenGate Hub (EC2 or on-premises)
2. Export tables from source DB for fixed SCN 3. Import tables to target DB
4. Configure EXTRACT process on source DB
5. Configure REPLICAT process on target DB starting after fixed SCN
6. Start processes to replicate changes
Ship trail files
Apply transactions
Read transactions
Create trail files EXTRACT
Oracle Source DB
REPLICAT
AWS Target DB
trail files
GoldenGate Hub
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Oracle GoldenGate: Pros
• Supports homogeneous and heterogeneous migrations
• Change Data Capture technology
• Can migrate subsets of tables and data
• Supports multitenant architecture
• Low performance impact on source and target DBs
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Oracle GoldenGate: Cons
• Extra cost option
• DDL replication is not supported in Oracle RDS – EC2 only
• Must maintain and configure GoldenGate Hub – EC2 instance or on-premises
• Monitor hub to restart processes in case of RDS failover
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Oracle Streams: Pros
• Free!
• Very customizable (can apply filters and transformations)
• Works reasonably well with clob replication
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Oracle Streams: Cons
• Deprecated in Oracle 12c
• Supports Oracle to Oracle migration only
• Does not work in multitenant architecture
• Cannot apply filters to tables with clob columns
• May encounter unique constraint bug during apply
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Case Study: Replicating Oracle to RDS
• Merge 2 multi-terabyte Oracle databases into 1 target RDS database
• Set up continuous replication using Streams
• Phased approach – Migrate subsets of tables
– Over a period of months
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Case Study Migration Diagram
Oracle Source SRC1
SCHEMA1 TABLE1, TABLE2, TABLE3, …
replicate and merge table data
Oracle Source SRC2
SCHEMA1 TABLE1, TABLE2, TABLE3, … AWS Target RDS
SCHEMA1 TABLE1, TABLE2, TABLE3, …
• Replicate most recent 90 days of data
• Transform key_ids
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Configuring Continuous Replication
• Initial database setup – Determine instance class and storage type (CPU, memory, size)
– Create target Oracle RDS database
• Tablespaces (use BIGFILE)
• Profiles
• Roles
• Users (schemas)
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Set Up Streams
SRC1_APPLY
SRC2_APPLY
SRC1_CAPTURE SRC2_CAPTURE
PROPAGATE_RDS PROPAGATE_RDS
Strmadmin schema
Strmadmin schema Strmadmin schema
via RDS_DBLINK via RDS_DBLINK
Add DML and DDL rules to capture
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Set Up Streams
• Create strmadmin user & tablespace in source & target DBs
• Create database link to RDS in source DBs
• Create streams capture and propagation in source DBs
• Create streams apply (one for each source) in target DB – See Addendum for source code create streams processes
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Configure Streams Rules in Src1 Capture
• Stop streams capture and propagation in Src1
• Add DDL rules, 1 for each table
• Add DML rules, 1 for each table – Add subset rules for filtered tables
– Add rule transformations as needed
• Instantiate tables
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Stop streams capture and propagation
exec dbms_capture_adm.set_parameter
('SRC1_CAPTURE', '_checkpoint_force', 'Y');
exec dbms_capture_adm.stop_capture
('SRC1_CAPTURE', FALSE);
exec dbms_propagation_adm.stop_propagation
('PROPAGATE_RDS');
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Add DDL Rules DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => <table name>,
streams_type => 'capture',
streams_name => 'SRC1_CAPTURE',
queue_name => 'STRMADMIN.SRC1_CAPTURE',
include_dml => FALSE,
include_ddl => TRUE,
include_tagged_lcr => TRUE,
ddl_rule_name => <ddl rule name>,
inclusion_rule => TRUE);
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Add DML Rules DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => <table name>,
streams_type => 'capture',
streams_name => 'SRC1_CAPTURE',
queue_name => 'STRMADMIN.SRC1_CAPTURE',
include_dml => TRUE,
include_ddl => FALSE,
include_tagged_lcr => TRUE,
dml_rule_name => <dml rule name>,
inclusion_rule => TRUE);
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
DML: Add rules for Filtered Tables
• Use ADD_SUBSET_RULES instead of ADD_TABLE_RULES
• Example: capture changes for table where – key_id >= 15000
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Add DML Subset Rules DBMS_STREAMS_ADM.ADD_SUBSET_RULES(
table_name => <table name>,
dml_condition => '(key_id >= 15000)',
streams_type => 'capture',
streams_name => 'SRC1_CAPTURE',
queue_name => 'STRMADMIN.SRC1_CAPTURE',
include_tagged_lcr => TRUE,
insert_rule_name => <insert rule name>,
update_rule_name => <update rule name>,
delete_rule_name => <delete rule name>);
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Instantiate Tables SELECT sys.dbms_flashback.get_system_change_number INTO <SCN> FROM dual;
dbms_capture_adm.prepare_table_instantiation(<table name>);
dbms_apply_adm.set_table_instantiation_scn@RDS_DBLINK (
source_object_name => <table name>,
source_database_name => 'SRC1.COMPANY.COM',
instantiation_scn => <SCN>,
apply_database_link => NULL);
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Instantiate Tables (cont'd)
-- Wait a few seconds to make sure instantiation is complete exec dbms_lock.sleep(5);
-- Get current scn and use it for the export col scn format 99999999999999999999999999
select timestamp_to_scn(systimestamp) as scn from dual;
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Export Tables from Src1: parfile
DIRECTORY = data_pump_dir
DUMPFILE = src1_schema1_group1.dmp
SCHEMAS = schema1
INCLUDE = TABLE:"IN ('TABLE1', 'TABLE2', 'TABLE3', 'TABLE4')"
QUERY = SCHEMA1.TABLE4:"WHERE (key_id >= 15000)"
LOGFILE = src1_schema1_group1_exp.log
FLASHBACK_SCN = <scn from query above>
COMPRESSION = ALL
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Export from Src1 and Transfer to RDS
-- Run the next command / as sysdba on the Src1 database server expdp parfile = src1_schema1_group1_exp.par
-- Transfer the export file to RDS: run as strmadmin in Src1 database BEGIN DBMS_FILE_TRANSFER.PUT_FILE(
source_directory_object => 'DATA_PUMP_DIR',
source_file_name => 'src1_schema1_group1.dmp',
destination_directory_object => 'DATA_PUMP_DIR',
destination_file_name => 'src1_schema1_group1.dmp',
destination_database => 'rds_dblink' ); END;
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Import Dump File into RDS
Contents of parfile on Src1 database server DIRECTORY = data_pump_dir
DUMPFILE = src1_schema1_group1.dmp
LOGFILE = rds_schema1_group1_imp.log
TRANSFORM = LOB_STORAGE:SECUREFILE
TABLE_EXISTS_ACTION = replace
Import dump file into RDS impdp admin@rds_dblink parfile = rds_schema1_group1_imp.par
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Start streams capture and propagation
• Run as strmadmin in Src1 database
exec dbms_capture_adm.start_capture
('SRC1_CAPTURE');
exec dbms_propagation_adm.start_propagation
('PROPAGATE_RDS');
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Validation
• Validate DDL – In Src1: grant select on schema1.table1 to public;
– In RDS: select * from dba_tab_privs where grantor='SCHEMA1' and grantee='PUBLIC' and type = 'TABLE';
• Validate DML – In Src1: insert data into a replicated table
– In RDS: query table to validate inserted row got replicated
• Back out all changes
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Clean Up
• In RDS, delete dump file and import log file exec utl_file.fremove('DATA_PUMP_DIR', 'src1_schema1_group1.dmp');
exec utl_file.fremove('DATA_PUMP_DIR', 'rds_schema1_group1_imp.log');
• As admin in RDS, recompile all invalid objects exec SYS.UTL_RECOMP.RECOMP_SERIAL('SCHEMA1');
• Run utlrp utility in Src1 DB to recompile all invalid objects
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Replicate Data from Src2 into RDS
• Same steps as for Src1 replication, with these changes: – Use SRC2_CAPTURE and SRC2_APPLY processes
– Do not replicate DDL if table structures are same
– If key values overlap in Src1 and Src2, add DML transformations
– Use CONTENT=DATA_ONLY when exporting the tables
– Use APPEND on table import from dump file instead of REPLACE
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Transforming Data Values
• Example:
• TABLE1 key_id in SRC1 range 1 - 99999
• TABLE1 key_id in SRC2 range 1 - 99999
• Add 100000 to all key_ids from SRC2 in RDS
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Transforming Data Values (cont'd)
• Create transform function in SRC2 strmadmin schema – See Addendum for source code change_key_id function
• Add SET_RULE_TRANSFORM functions to streams rules created via ADD_TABLE_RULES or ADD_SUBSET_RULES
• SRC2 data export: use REMAP_DATA to call package function to transform exported key_id values – See Addendum for source code rds_remap.convert_key_id
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Add DML Streams Transformation Rules DBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION(
rule_name => <insert rule name>,
transform_function => 'strmadmin.change_key_id');
DBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION(
rule_name => <update rule name>,
transform_function => 'strmadmin.change_key_id');
DBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION(
rule_name => <delete rule name>,
transform_function => 'strmadmin.change_key_id');
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Add Transform Function to SRC2 Export DIRECTORY = data_pump_dir
DUMPFILE = src2_schema1_group1.dmp
SCHEMAS = schema1
CONTENT = DATA_ONLY
INCLUDE = TABLE:"IN ('TABLE1', 'TABLE2', 'TABLE3', 'TABLE4')"
QUERY = SCHEMA1.TABLE4:"WHERE (key_id >= 15000)"
REMAP_DATA = schema1.table4.key_id:strmadmin.rds_remap.convert_key_id
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Migration Best Practices
• Partitioned tables – Partition maintenance operations can be replicated SRC1 to RDS via
DDL rules
– Turn off DDL rules in SRC2
• Pl/SQL and Views: manually run source code in RDS
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Migration Best Practices (cont'd)
• Scheduled jobs: disable most in RDS until switchover
• Synonyms: create in target DB
• Foreign key constraints: disable in target DB – Better replication performance
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Migration Best Practices (cont'd)
• The following objects are not replicated via Streams: – Triggers
– Materialized views
– Sequences
• How to handle these objects?
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Triggers
• Exclude from data pump import into RDS – Add the following line to import parameter file:
EXCLUDE = TRIGGER
• Run script to manually create triggers in RDS – Disable all triggers until switchover
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Materialized Views
• Exclude mv logs from data pump import into RDS – Add the following lines to import parameter file:
EXCLUDE = MATERIALIZED_VIEW_LOG
EXCLUDE = TABLE:"like 'MLOG$%'"
• Create directly in RDS using prebuilt tables
• Do an initial refresh to populate each table with data
• Create scheduled jobs in RDS to refresh data periodically
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Sequences
• Create in RDS as part of full schema export/import, or manually run a script
• Nextval will not increment as part of streams replication
• At cutover, write a script to adjust the value of nextval: – Max(current table value populated via sequence in RDS) +
increment
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Validation and Application Testing
• Destination RDS database is read-only until switchover
• Testing: restore copy of RDS database from snapshot – Run switchover scripts on RDS copy
– Point applications to RDS copy (revised tnsnames.ora file)
– Conduct testing bashes to validate and performance test critical applications
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Switchover Steps
• Stop job queue processes in SRC1 and SRC2
• Shut down all applications in SRC1 and SRC2
• Stop streams capture & propagation processes, SRC1 & 2
• Run switchover script in RDS – Stop Streams apply processes
– Set NEXTVAL for all sequences
– Enable all disabled scheduled jobs and triggers
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Switchover Steps (cont'd)
– Drop temporary scheduled jobs and procedures (materialized view refreshes)
– Enable novalidate all disabled foreign key constraints
• Push new tnsnames.ora files to all application servers
• Shut down SRC1 and SRC2 databases and listeners
• Start all applications in RDS database
• Validate!
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Questions
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Contact Information
• http://www.returnpath.com
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Addendum
• The following slides contain sample source code referenced in previous slides.
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Streams Processes
-- Run as strmadmin in source database (SRC1)
BEGIN
DBMS_STREAMS_ADM.SET_UP_QUEUE(
queue_table => 'SRC1_CAPTURE',
storage_clause => NULL,
queue_name => 'SRC1_CAPTURE',
queue_user => 'STRMADMIN');
END;
/
BEGIN
DBMS_RULE_ADM.CREATE_RULE_SET(
rule_set_name => 'STRMADMIN.SRC1_CAPTURE',
evaluation_context => 'SYS.STREAMS$_EVALUATION_CONTEXT');
END;
/
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Streams Processes (cont'd)
-- first_scn must be lower than the start_scn
DECLARE
v_first_scn NUMBER;
v_start_scn NUMBER;
BEGIN
DBMS_CAPTURE_ADM.BUILD(v_first_scn);
dbms_output.put_line(v_first_scn);
DBMS_LOCK.SLEEP(10);
select timestamp_to_scn(systimestamp) into v_start_scn from dual;
dbms_output.put_line(v_start_scn);
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Streams Processes (cont'd) DBMS_CAPTURE_ADM.CREATE_CAPTURE(
queue_name => 'STRMADMIN.SRC1_CAPTURE',
capture_name => 'SRC1_CAPTURE',
rule_set_name => 'STRMADMIN.SRC1_CAPTURE',
first_scn => v_first_scn,
start_scn => v_start_scn,
checkpoint_retention_time => 3);
END;
/
BEGIN
DBMS_PROPAGATION_ADM.CREATE_PROPAGATION(
propagation_name => 'PROPAGATE_RDS',
source_queue => 'STRMADMIN.SRC1_CAPTURE',
destination_queue => 'STRMADMIN.SRC1_APPLY',
destination_dblink => 'RDS_DBLINK',
queue_to_queue => FALSE);
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Streams Processes (cont'd)
DBMS_PROPAGATION_ADM.STOP_PROPAGATION('PROPAGATE_RDS');
END;
/
-- Run as strmadmin in Oracle RDS target database
BEGIN
DBMS_STREAMS_ADM.SET_UP_QUEUE(
queue_table => 'SRC1_APPLY',
storage_clause => NULL,
queue_name => 'SRC1_APPLY',
queue_user => 'STRMADMIN');
END;
/
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Streams Processes (cont'd) BEGIN
DBMS_APPLY_ADM.CREATE_APPLY(
queue_name => 'STRMADMIN.SRC1_APPLY',
apply_name => 'SRC1_APPLY',
apply_user => 'STRMADMIN',
apply_captured => TRUE);
END;
/
BEGIN
DBMS_APPLY_ADM.SET_PARAMETER(
apply_name => 'SRC1_APPLY',
parameter => 'DISABLE_ON_ERROR',
value => 'N');
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Streams Processes (cont'd)
DBMS_APPLY_ADM.SET_PARAMETER(
apply_name => 'SRC1_APPLY',
parameter => 'PARALLELISM',
value => '1');
DBMS_APPLY_ADM.SET_PARAMETER(
apply_name => 'SRC1_APPLY',
parameter => 'COMMIT_SERIALIZATION',
value => 'FULL');
DBMS_APPLY_ADM.SET_PARAMETER (
apply_name => 'SRC1_APPLY',
parameter => 'txn_lcr_spill_threshold',
value => '2000000');
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Streams Processes (cont'd)
DBMS_APPLY_ADM.SET_PARAMETER (
apply_name => 'SRC1_APPLY',
parameter => 'txn_age_spill_threshold',
value => 'infinite');
END;
/
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Transform Function in Src2
CREATE OR REPLACE FUNCTION STRMADMIN.change_key_id (in_any IN ANYDATA)
RETURN ANYDATA
IS
lcr SYS.lcr$_row_record;
rc NUMBER;
ob_owner VARCHAR2(30);
ob_name VARCHAR2(30);
ob_column VARCHAR2(30) := 'KEY_ID';
x_anydata ANYDATA;
x_number NUMBER;
y_number NUMBER;
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Transform Function (cont'd) BEGIN
-- Get the type of object
-- Check if the object type is SYS.LCR$_ROW_RECORD
IF in_any.gettypename = 'SYS.LCR$_ROW_RECORD' THEN
-- Put the row LCR into lcr
rc := in_any.getobject(lcr);
-- Get the object owner and name
ob_owner := lcr.get_object_owner();
ob_name := lcr.get_object_name();
-- Get the old value of the key_id column in the LCR
x_anydata := lcr.get_value('old', ob_column);
IF x_anydata IS NOT NULL THEN
-- Put the column value into x_number
rc := x_anydata.getnumber(x_number);
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Transform Function (cont'd) -- Convert to the new key_id value
y_number := x_number + 1000000;
lcr.set_value('old', ob_column, anydata.convertnumber(y_number));
END IF;
-- Get the new value of the key_id column in the LCR
x_anydata := lcr.get_value('new', ob_column, 'N');
IF x_anydata IS NOT NULL THEN
-- Put the column value into x_number
rc := x_anydata.getnumber(x_number);
-- Convert to the new key_id value
y_number := x_number + 1000000;
lcr.set_value('new', ob_column, anydata.convertnumber(y_number));
END IF;
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Transform Function (cont'd)
RETURN anydata.convertobject(lcr);
END IF;
RETURN in_any;
END;
/
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Create Transform Package Function
CREATE OR REPLACE PACKAGE STRMADMIN.rds_remap
AS
FUNCTION convert_key_id (x_number IN NUMBER)
RETURN NUMBER;
END rds_remap;
/
www.rmoug.org February 20-22, 2018 | Westin Westminster Hotel | Westminster, CO
Transform Package Function (cont'd)
CREATE OR REPLACE PACKAGE BODY STRMADMIN.rds_remap
AS
FUNCTION convert_key_id (x_number IN NUMBER)
RETURN NUMBER
IS
y_number NUMBER;
BEGIN
y_number := x_number + 1000000;
RETURN y_number;
END convert_key_id;
END rds_remap;
/