Oracle
 sql >> Baza danych >  >> RDS >> Oracle

PostgreSQL 9.5 - nie działa dekodowanie / wybieranie przypadku, aby rozwiązać błąd za pomocą utf8

Błąd występuje, gdy wartości są przesyłane z Oracle do PostgreSQL, więc przetwarzanie końcowe nie zapobiegnie błędowi.

Dla celów demonstracyjnych stwórzmy tabelę Oracle, która przedstawia problem:

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;

Stwórzmy dla tego obcą tabelę w 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

Teraz najłatwiej byłoby utworzyć obcą tabelę, która odfiltruje znaki zerowe:

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)

Inną, mniej wydajną opcją byłoby utworzenie funkcji, która wyłapuje i zgłasza złe linie, aby można było je naprawić po stronie 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. gdzie rownum=1 zapytanie zajmuje czas w Oracle

  2. Eksportowanie żądania sql do csv zamiast danych tabeli

  3. Nie rozumiem, dlaczego moja grupa według upada

  4. Dlaczego funkcje agregujące nie są dozwolone w klauzuli where?

  5. Jak mogę zablokować pojedynczy wiersz w Oracle SQL?