Цель: Я хочу, чтобы загрузить данные из TABLE_X
, расположенных в DBLINK1
в TABLE_Y
находится в DBLINK2
.Oracle слияния с преобразованием кодировки через несколько DBLinks
Мне также нужно обрабатывать разные кодировки, поэтому я использую функцию oracle CONVERT
и функцию TRANSLATE
для замены акцентированных символов.
Упрощенная MERGE
команда будет выглядеть следующим образом:
MERGE INTO [email protected] TABLE_ACTUAL
USING(SELECT ID,
TRANSLATE(CONVERT(NAME, 'WE8PC850', 'WE8ISO8859P1'), 'Ã', 'A') NAME
FROM [email protected]) TABLE_NEW
ON (TABLE_ACTUAL.ID = TABLE_NEW.ID)
WHEN MATCHED THEN
UPDATE SET NAME = TABLE_NEW.NAME
WHEN NOT MATCHED THEN
INSERT (ID, NAME) VALUES(TABLE_NEW.ID, TABLE_NEW.NAME);
Эта команда работает без вопроса, но значения в столбце NAME
не конвертируются и не переводятся, когда я смотрю в [email protected]
.
Когда я использую несколько иной подход, как показано ниже, операции CONVERT
и TRANSLATE
выполнены успешно.
DECLARE
CURSOR CUR_TABLE IS
SELECT ID,
TRANSLATE(CONVERT(NAME, 'WE8PC850', 'WE8ISO8859P1'), 'Ã', 'A') NAME
FROM [email protected];
BEGIN
FOR REG_TABLE IN CUR_TABLE LOOP
BEGIN
INSERT INTO [email protected](ID, NAME)
VALUES(REG_TABLE.ID, REG_TABLE.NAME);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
UPDATE [email protected]
SET NAME = REG_TABLE.NAME
WHERE ID = REG_TABLE.ID;
END;
END LOOP;
END;
Проблема со вторым подходом заключается в том, что для выполнения выполнения требуется больше времени, чем команда слияния.
Вопрос: Есть ли правдоподобное объяснение, почему CONVERT
и TRANSLATE
функции не будут работать при использовании с командой MERGE
?
Дополнительная информация:
CURRENT DB: Oracle 10
DBLINK2 (destination): Oracle 12
DBLINK1 (origin): Unknown version
Update: Как предложил @Kacper, я попытался с помощью DRIVING_SITE
намек, чтобы заставить оракул оценить выражения в локальной базе данных.
Окончательный рабочий раствор:
MERGE INTO [email protected] TABLE_ACTUAL
USING(SELECT /*+DRIVING_SITE(DUAL)*/
ID,
TRANSLATE(CONVERT(NAME, 'WE8PC850', 'WE8ISO8859P1'), 'Ã', 'A') NAME
FROM [email protected],
DUAL
WHERE ID > 0) TABLE_NEW
ON (TABLE_ACTUAL.ID = TABLE_NEW.ID)
WHEN MATCHED THEN
UPDATE SET NAME = TABLE_NEW.NAME
WHEN NOT MATCHED THEN
INSERT (ID, NAME) VALUES(TABLE_NEW.ID, TABLE_NEW.NAME);
достаточно Жутко, он только полностью работал после того, как я поставил манекен, где положение (ID > 0
) на источник SELECT
.
Подсказка DRIVING_SITE была ключом. Я обновил вопрос с окончательным решением. Благодарю. –