Oracle通过多个DBLinks进行字符集转换合并



目标:我想将数据从位于DBLINK1TABLE_X加载到位于DBLINK2TABLE_Y中。

我还需要处理不同的字符集,所以我使用oracleCONVERT函数和TRANSLATE函数来替换重音字符。

简化的MERGE命令如下所示:

MERGE INTO TABLE_Y@DBLINK2 TABLE_ACTUAL
USING(SELECT ID,
             TRANSLATE(CONVERT(NAME, 'WE8PC850', 'WE8ISO8859P1'), 'Ã', 'A') NAME
        FROM TABLE_X@DBLINK1) 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);

这个命令运行时没有问题,但当我查看TABLE_Y@DBLINK2时,NAME列中的值不会被转换或转换。

当我使用如下所示的稍微不同的方法时,CONVERTTRANSLATE操作成功完成。

DECLARE
  CURSOR CUR_TABLE IS
    SELECT ID,
           TRANSLATE(CONVERT(NAME, 'WE8PC850', 'WE8ISO8859P1'), 'Ã', 'A') NAME
      FROM TABLE_X@DBLINK1;
BEGIN
  FOR REG_TABLE IN CUR_TABLE LOOP  
    BEGIN
      INSERT INTO TABLE_Y@DBLINK2(ID, NAME)
      VALUES(REG_TABLE.ID, REG_TABLE.NAME);
      EXCEPTION
        WHEN DUP_VAL_ON_INDEX THEN
          UPDATE TABLE_Y@DBLINK2
            SET NAME = REG_TABLE.NAME
          WHERE ID = REG_TABLE.ID;
     END;
   END LOOP;
END;

第二种方法的问题是,与merge命令相比,它的执行时间要长得多。

问题:对于CONVERTTRANSLATE函数与MERGE命令一起使用时无法工作的原因,是否有任何合理的解释?

其他信息:

CURRENT DB: Oracle 10
DBLINK2 (destination): Oracle 12
DBLINK1 (origin): Unknown version

更新:正如@Kapper建议的那样,我尝试使用DRIVING_SITE提示来强制oracle评估本地数据库上的表达式。

最终工作解决方案:

MERGE INTO TABLE_Y@DBLINK2 TABLE_ACTUAL
USING(SELECT /*+DRIVING_SITE(DUAL)*/ 
             ID,
             TRANSLATE(CONVERT(NAME, 'WE8PC850', 'WE8ISO8859P1'), 'Ã', 'A') NAME
        FROM TABLE_X@DBLINK1, 
             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);

奇怪的是,我在源SELECT上放置了一个伪where子句(ID > 0(之后,它才完全起作用。

我所理解的不同之处在于,在方法2中,您将数据从DBLINK1拉到本地数据库,在本地数据库上进行转换,然后将转换后的数据插入DBLINK2。方法1将在DBLINK1DBLINK2上进行翻译,您可以尝试通过DRIVING_SITE提示来控制它。

我不确定它是否有帮助,但我会尝试create view db1_v as SELECT ID, TRANSLATE(CONVERT(NAME, 'WE8PC850', 'WE8ISO8859P1'), 'Ã', 'A') NAME FROM TABLE_X@DBLINK1,然后使用视图进行合并。

在最坏的情况下,如果这对create table t1 as SELECT ID, TRANSLATE(CONVERT(NAME, 'WE8PC850', 'WE8ISO8859P1'), 'Ã', 'A') NAME FROM TABLE_X@DBLINK1没有帮助,则使用新表进行合并。

最新更新