ORACLE GOLDEN GATE COLSEXCEPT не работает

Я пытаюсь скопировать таблицы из производства в хранилище данных. Есть столбцы, для которых я не хочу транзакции, когда обновление выполняется только для этих столбцов. У меня сложилось впечатление, что мне нужно использовать команду COLSEXCEPT

(
https://docs.oracle.com/goldengate/1212/gg-winux/GWURF/gg_parameters160.htm#GWURF546

{COLS | COLSEXCEPT} (column_list) Selects or excludes columns for processing.
TABLE
)  

В моей таблице столбец BL_ARREARS_IND необходимо исключить, поскольку его нет в моей целевой таблице. Когда я обновляю только столбец BL_ARREARS_IND в источнике, он по-прежнему регистрирует транзакцию по очереди, отправляя ее на целевой сервер.

У меня есть выписка и настроенный насос.

EXTRACT extbill

SETENV (ORACLE_SID=******)
SETENV (ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/dbhome_1)
USERID *****, PASSWORD *****
EXTTRAIL /u01/dwdev/oggdev/product/12.1.2/oggcore_2/dirdat/lb
TRANLOGOPTIONS ASMUSER SYS@ASM8, ASMPASSWORD ******

TABLE tmp.bill, &
KEYCOLS(ACCT_ID, BILL_SEQ_NO), &
**COLSEXCEPT(BL_ARREARS_IND);**

DISCARDFILE ./dwdev_ggdev_bill.dsc, APPEND
DiscardRollover at 02:00 ON SUNDAY

EXTRACT pumpbill

RMTHOST tst.corp.intranet, MGRPORT 7812
RMTTRAIL /u01/dwtst/oggdev/product/12.1.2/oggcore_2/dirdat/rb
TABLE tmp.bill **COLSEXCEPT(BL_ARREARS_IND);**

Что мне не хватает?

1 ответ

Я неправильно понял команду COLSEXCEPT. Я думал, что транзакция будет создана, только если было внесено изменение в поле, которого нет в списке COLSEXCEPT. Он по-прежнему создает транзакцию, но просто не отправляет эти поля в целевую базу данных (все еще не уверен, зачем создавать транзакцию для изменений в исключаемых полях).

Я уверен, что есть лучший способ, но я смог заставить его работать, используя то, что я называю обходным путем, применив фильтр к таблице в извлечении. Это был громоздкий процесс, потому что в таблице 82 поля. Пришлось сравнивать ПЕРЕД изображением с ПОСЛЕ изображения для всех остальных 81 полей, которые мне нужны.

Когда у вас есть столько аргументов в ФИЛЬТРЕ, вы должны увеличить FUNCTIONSTACKSIZE, чтобы вместить (что в моем случае потребовало администратора базы данных, чтобы внести изменения).

Я знаю, что должен быть лучший способ справиться с этим, но вот код, который работал для меня:


ТАБЛИЦА tmp.bill, KEYCOLS(ACCT_ID, BILL_SEQ_NO), COLSEXCEPT(BL_ARREARS_IND), ФИЛЬТР (ОБНОВЛЕНИЕ,((@BEFORE(ACCT_ID)) <> @AFTER (ACCT_ID)) или (@BEFORE (BILL_SEOF))) или (@BEFORE (ACTUAL_BALANCE_AMT) <> @AFTER (ACTUAL_BALANCE_AMT)) или (@STREQ(@BEFORE(AFTER_CYCLE_CHG_IND),@AFTER(AFTER_CYCLE_CHG_IND)) = 0) или (@BEF_GID) (AGB_GID) (AGB_GID) (AGEGID) (AGEGTER (AGEGTER))) или (@STREQ(@BEFORE(APPLICATION_ID),@AFTER(APPLICATION_ID)) = 0) или (@STREQ(@BEFORE(BANK_ACCOUNT_NO),@AFTER(BANK_ACCOUNT_NO)) = 0) или (@STREQ(@BEFORE(BANK_CODE),@AFTER(BANK_CODE)) = 0) или (@STREQ(@BEFORE(BAN_STATUS),@AFTER(BAN_STATUS)) = 0) или (@STREQ(@BEFORE(BAN_STATUS_DATE),@AFTER(BAN_STATUS_DATE) =) 0) или (@BEFORE (BF_ADJ) <> @AFTER (BF_ADJ)) или (@STREQ (@BEFORE (BF_BTN), @ AFTER (BF_BTN)) = 0) или (@BEFORE(BF_CALL_CHG) <> @AFTER(BF_CALL_CHG)) или (@BEFORE(BF_IMM_ADJ) <> @AFTER(BF_IMM_ADJ)) или (@BEFORE(BF_MON_SRV_CHG) <> @AFTER(BF_MON_SRV_CHG)) или (@BEFORE(BF_ONE_TIME_CRG) (B) или @F) @> ДО (BF_TAXS) <> @AFTER(BF_TAXS)) или (@STREQ(@BEFORE(BILLING_METHOD),@AFTER(BILLING_METHOD)) = 0) или (@STREQ(@BEFORE(BILL_CONF_STATUS),@AFTER(BILL_CONF_STATUS)) = 0) или @ @BEFORE(BILL_DATE),@AFTER(BILL_DATE)) = 0) или (@STREQ(@BEFORE(BILL_DUE_DATE),@AFTER(BILL_DUE_DATE)) = 0) или (@STREQ(@BEFORE(BILL_STATUS_DATE)),@AFTER(BILL_STAT)) = 0) или (@STREQ(@BEFORE(BL_BAL_HANDLE_IND),@AFTER(BL_BAL_HANDLE_IND)) = 0) или (@STREQ(@BEFORE(CARRY_OVER_IND),@AFTER(CARRY_OVER_IND)) = 0) или (@BEFORE CH_BAL_CHGS) <> @AFTER(CH_BAL_CHGS)) или (@STREQ(@BEFORE(CREDIT_CARD_NO),@AFTER(CREDIT_CARD_NO)) = 0) или (@STREQ(@BEFORE(CREDIT_CARD_TYPE)) CRD (CR) (CRF) = CRED (CRT) = CRED (CRD)) CRED или (@STREQ(@BEFORE(CR_CARD_AUTH_CODE),@AFTER(CR_CARD_AUTH_CODE)) = 0) или (@STREQ(@BEFORE(CR_CARD_EXP_DATE),@AFTER(CR_CARD_EXP_DATE)) = 0) или (@REFRE) (@BEFORE) ПОСЛЕ (CURR_CHARGE_AMT)) или (@BEFORE (CURR_CREDIT_AMT) <> @AFTER (CURR_CREDIT_AMT)) или (@BEFORE (CURR_OC_CHRG_AMT) <> @AFTER (CURR_OC_CHRG_AMT)) или (@BEFORE (CURR_RC_CHRG_AMT) <> @AFTER (ТОК _RC_CHRG_AMT)) или (@BEFORE (CURR_UC_CHRG_AMT) <> @AFTER (CURR_UC_CHRG_AMT)) или (@STREQ (@BEFORE (CYCLE_CLOSE_DATE), @ AFTER (CYCLE_CLOSE_DATE) @BF) (0) или 0C () (0) или 0C) CYCLE_CODE)) или (@BEFORE (CYCLE_RUN_MONTH) <> @AFTER (CYCLE_RUN_MONTH)) или (@BEFORE (CYCLE_RUN_YEAR) <> @AFTER (CYCLE_RUN_YEAR)) или (@BEFORE (DEPOSTF) () @BEFORE (DEPOSIT_REQ_AMT) <> @AFTER (DEPOSIT_REQ_AMT)) или (@STREQ (@BEFORE (DL_SERVICE_CODE), @ AFTER (DL_SERVICE_CODE)) = 0) или (@BEFORE (DL_UPDATE_A)) @BEFORE (FGN_COUNTY_TAX_AMT) <> @AFTER (FGN_COUNTY_TAX_AMT)) или (@BEFORE (FGN_FED_TAX_AMT) <> @AFTER (FGN_FED_TAX_AMT)) или (@BEFORE (FGN_LT_TA_F_TALTF) (FGF) (FGF) (FGF) (FGF) (FGF) (FGF) (FGF) (FGF) (FGF) (FGT) FALT) <> @AFTER (FGN_STATE_TAX_AMT)) или (@BEFORE (FREE_MINUTE_STATUS) <> @AFTER (FREE_MINUTE_STATUS)) или (@BEFORE (LATE_PYM_BASE_AMT) <> @AFTER (LATE_PYM_B) (MASTER) () (MASTER) ()) MASTER_BAN)) или (@BEFORE (MB_BILL_SEQ_NO) <> @AFTER (MB_BILL_S EQ_NO)) или (@BEFORE (NM_ADR_LINK_SEQ_NO) <> @AFTER (NM_ADR_LINK_SEQ_NO)) или (@BEFORE (NON_TELECOM_AMT) <> @AFTER (NON_TELECOM_AMT) (@_F_NF) (или @NOF) (NB) @BEFORE (OPERATOR_ID) <> @AFTER (OPERATOR_ID)) или (@BEFORE (PAST_DUE_AMT) <> @AFTER (PAST_DUE_AMT)) или (@STREQ (@BEFORE (PAYMENT_METHOD)),@AFTER(PAYMENT_METHOD)) @BEFORE (PAY_ARR_AMT_DUE) <> @AFTER (PAY_ARR_AMT_DUE)) или (@BEFORE (PAY_ARR_AMT_REM) <> @AFTER (PAY_ARR_AMT_REM)) или (@STREQ(@BEFORE(PRD_C_RD)) (): PRD_C_RG) @STREQ (@BEFORE (PRD_CVRG_STRT_DATE),@AFTER(PRD_CVRG_STRT_DATE)) = 0) или (@BEFORE (PREV_BALANCE_AMT) <> @AFTER (PREV_BALANCE_AMT)) или (@STREQ, @_DATE) (AFTER) (AFTER) = 0) или (@STREQ(@BEFORE(PRODUCTION_REQUEST),@AFTER(PRODUCTION_REQUEST)) = 0) или (@STREQ(@BEFORE(PRODUCTION_TYPE)),@AFTER(PRODUCTION_TYPE)) = 0) или (@BEFORE (PRODUCTS_NUM_CALLS) <> @AFTER (PRODUCTS_NUM_CALLS)) или (@BEFORE (PRODUCTS_NUM_MINS) <> @AFTER (PRODUCTS_NUM_MINS)) или (@BEF ORE (PYM_RECEIVED_AMT) <> @AFTER (PYM_RECEIVED_AMT)) или (@STREQ (@BEFORE (SYS_CREATION_DATE), @ AFTER (SYS_CREATION_DATE)) = 0) или (@STREQ (@BEFORE (SYS_ATED))) 0) или (@BEFORE(TAX_FED_AMT) <> @AFTER(TAX_FED_AMT)) или (@BEFORE(TAX_FED_USF_AMT) <> @AFTER(TAX_FED_USF_AMT)) или (@BEFORE(TAX_LOC_AMT) <> @AFTER(TAX) (TAX) (TAX) BEFORE(TAX_ROAM_AIR) <> @AFTER(TAX_ROAM_AIR)) или (@BEFORE(TAX_ROAM_SRV_CHARGE) <> @AFTER(TAX_ROAM_SRV_CHARGE)) или (@BEFORE(TAX_ROAM_TOLL) <> @ATERT (TAX) TAF (TAF) (TAF) (TAF) (TAF) (TAF) (TAF) (TAF) (TAF) (TAF) (TAF) (TAF) (TAF) > @AFTER (TAX_STT_AMT)) или (@BEFORE (TELECOM_AMT) <> @AFTER (TELECOM_AMT)) или (@BEFORE (TOTAL_BILLED_ADJUST) <> @AFTER (TOTAL_BILLED_ADJUST)) или (@BEFORE_TAR)) или (@BEFORE (TOTAL_COUNTY_TAX) <> @AFTER (TOTAL_COUNTY_TAX)) или (@BEFORE (TOTAL_DUE_AMT) <> @AFTER (TOTAL_DUE_AMT)) или (@BEFORE (TOTAL_TAX_FEES) <>)TAF ())

Этот код не мог сравнивать нули. Я придумал этот макрос, который дал мне правильный результат.

Filename: check_col.mac

Contents:

MACRO #check_col
PARAMS (#ICOL)
BEGIN
(
(0 = @IF (@COLTEST (@BEFORE(#ICOL), NULL, MISSING),0,1) AND 1 = @IF (@COLTEST (#ICOL, NULL, MISSING), 0, 1))
OR
(1 = @IF (@COLTEST(@BEFORE(#ICOL), NULL, MISSING), 0, 1) AND 0 = @IF (@COLTEST (#ICOL, NULL, MISSING), 0, 1))
OR
(0 = @STREQ(@BEFORE(#ICOL),#ICOL))
)
END;

Вы можете использовать этот макрос в файле INC для сопоставления, как показано ниже:

INCLUDE dirprm/check_col.mac

TABLE S1.T1, KEYCOLS(COL1, COL2), COLSEXCEPT(COL123), FILTER(ON UPDATE,(#check_col(COL3) or #check_col(COL4));

Если вы сопоставите более 5 столбцов таким образом, код выдаст ошибку STACK SIZE NOT ENOUGH, FUNCTIONSTACKSIZE = 5000 решает ее. Сообщите мне, какие отрицательные эффекты имеет этот параметр.

Другие вопросы по тегам