sql >> データベース >  >> RDS >> Oracle

PostgreSQL 9.5 - utf8 でエラーを解決するためのケースのデコード / 選択が機能しない

    値が Oracle から PostgreSQL に転送されるときにエラーが発生するため、後処理ではエラーを防止できません。

    デモンストレーションのために、問題を示す Oracle テーブルを作成してみましょう:

    CREATE TABLE nulltest(
       id number(5) CONSTRAINT nulltest_pkey PRIMARY KEY,
       val varchar2(10 CHAR)
    );
    
    INSERT INTO nulltest VALUES (1, 'schön');
    INSERT INTO nulltest VALUES (2, 'bö' || CHR(0) || 'se');
    INSERT INTO nulltest VALUES (3, 'egal');
    
    COMMIT;
      

    PostgreSQL に外部テーブルを作成しましょう:

    CREATE FOREIGN TABLE nulltest (
       id integer OPTIONS (key 'true') NOT NULL,
       val varchar(10)
    ) SERVER oracle
       OPTIONS (table 'NULLTEST');
    
    SELECT * FROM nulltest;
    
    ERROR:  invalid byte sequence for encoding "UTF8": 0x00
    CONTEXT:  converting column "val" for foreign table scan of "nulltest", row 2
      

    最も簡単な方法は、ゼロ文字を除外する外部テーブルを作成することです:

    CREATE FOREIGN TABLE filter_nulltest (
       id integer OPTIONS (key 'true') NOT NULL,
       val varchar(10)
    ) SERVER oracle
       OPTIONS (table '(SELECT id, replace(val, CHR(0), NULL) FROM nulltest)');
    
    SELECT * FROM filter_nulltest;
    
    ┌────┬───────┐
    │ id │  val  │
    ├────┼───────┤
    │  1 │ schön │
    │  2 │ böse  │
    │  3 │ egal  │
    └────┴───────┘
    (3 rows)
      

    効率の悪いもう 1 つのオプションは、Oracle 側で修正できるように、不正な行をキャッチして報告する関数を作成することです。

    CREATE OR REPLACE FUNCTION get_nulltest() RETURNS SETOF nulltest
       LANGUAGE plpgsql AS
    $$DECLARE
       v_id integer;
       n nulltest;
    BEGIN
       FOR v_id IN SELECT id FROM nulltest
       LOOP
          BEGIN
             SELECT nulltest.* INTO n
                FROM nulltest
                WHERE id = v_id;
             RETURN NEXT n;
          EXCEPTION
             WHEN OTHERS THEN
                RAISE NOTICE 'Caught error % for id=%: %', SQLSTATE, v_id, SQLERRM;
          END;
       END LOOP;
    END;$$;
    
    SELECT * FROM get_nulltest();
    
    NOTICE:  Caught error 22021 for id=2: invalid byte sequence for encoding "UTF8": 0x00
    ┌────┬───────┐
    │ id │  val  │
    ├────┼───────┤
    │  1 │ schön │
    │  3 │ egal  │
    └────┴───────┘
    (2 rows)
      


    1. 最新のアプリケーションには、OracleのUCPまたはHikariCPを使用する必要がありますか?

    2. PLS-00352およびPLS-00201DBリンク経由

    3. SQLDeveloperが起動しない

    4. 1つのcreateステートメントのみを使用しているのにSQLスクリプトの「createtable」が3回実行されるのはなぜですか?