sql >> Database teknologi >  >> RDS >> Oracle

PostgreSQL 9.5 - afkode / vælg sag for at løse fejl med utf8 virker ikke

Fejlen opstår, når værdierne overføres fra Oracle til PostgreSQL, så efterbehandling forhindrer ikke fejlen.

Lad os for demonstrationens skyld oprette en Oracle-tabel, der viser problemet:

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;

Lad os oprette en fremmed tabel i PostgreSQL til det:

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

Nu ville det nemmeste være at oprette en fremmed tabel, der filtrerer nultegnene væk:

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)

En anden, mindre effektiv, mulighed ville være at oprette en funktion, der fanger og rapporterer dårlige linjer til dig, så du kan rette dem på Oracle-siden:

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. MySQL viser aktuelle forbindelsesoplysninger

  2. php imap - få brødtekst og lav almindelig tekst

  3. oracle - konverter mange datoformater til en enkelt formateret dato

  4. Tæl adskilt pr. regnskabsår og vis alle datoer i forespørgselsresultatet