PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Przechowywanie json, jsonb, hstore, xml, enum, ipaddr itp. kończy się niepowodzeniem, ponieważ kolumna x jest typu json, ale wyrażenie ma charakter zmienny

Dlaczego tak się dzieje

Problem polega na tym, że PostgreSQL zbyt rygorystycznie podchodzi do rzutowania między tekstowymi i nietekstowymi typami danych. Nie pozwoli na niejawne rzutowanie (bez CAST lub :: w SQL) z typu tekstowego, takiego jak text lub varchar (character varying ) do typu nietekstowego podobnego do tekstu, takiego jak json , xml itp.

Sterownik PgJDBC określa typ danych varchar kiedy wywołasz setString aby przypisać parametr. Jeśli typ bazy danych kolumny, argumentu funkcji itp. nie jest w rzeczywistości varchar lub text , ale zamiast innego typu pojawia się błąd typu. Dotyczy to również wielu innych sterowników i ORM-ów.

PgJDBC:stringtype=unspecified

Najlepszą opcją podczas korzystania z PgJDBC jest ogólnie przekazanie parametru stringtype=unspecified . Zastępuje to domyślne zachowanie przekazywania setString wartości jako varchar i zamiast tego pozostawia bazę danych, aby "odgadła" ich typ danych. W prawie wszystkich przypadkach robi to dokładnie to, czego chcesz, przekazując ciąg do walidatora danych wejściowych dla typu, który chcesz przechowywać.

Wszystko:CREATE CAST ... WITH FUNCTION ...

Możesz zamiast tego CREATE CAST zdefiniować rzutowanie specyficzne dla typu danych, aby zezwolić na to na podstawie typu po typie, ale może to mieć skutki uboczne w innych miejscach. Jeśli to zrobisz, nie użyj WITHOUT FUNCTION rzutowania, ominą sprawdzanie poprawności typu i spowodują błędy. Musisz użyć funkcji wejścia/walidacji dla typu danych. Korzystanie z CREATE CAST jest odpowiedni dla użytkowników innych sterowników baz danych, którzy nie mają możliwości zatrzymania sterownika określającego typ parametrów łańcucha/tekstu.

np.

CREATE OR REPLACE FUNCTION json_intext(text) RETURNS json AS $$
SELECT json_in($1::cstring); 
$$ LANGUAGE SQL IMMUTABLE;

CREATE CAST (text AS json) 
WITH FUNCTION json_intext(text) AS IMPLICIT;

Wszystko:obsługa typu niestandardowego

Jeśli Twój ORM na to pozwala, możesz zaimplementować niestandardową procedurę obsługi typu dla typu danych i tego konkretnego ORM. Jest to szczególnie przydatne, gdy używasz natywnego typu Java, który dobrze odwzorowuje typ PostgreSQL, zamiast używania String , ale może również działać, jeśli Twój ORM pozwala określić procedury obsługi typu za pomocą adnotacji itp.

Metody implementacji niestandardowych programów obsługi typów są specyficzne dla sterownika, języka i ORM. Oto przykład dla Javy i Hibernate dla json .

PgJDBC:wpisz procedurę obsługi za pomocą PGObject

Jeśli używasz natywnego typu Java w Javie, możesz rozszerzyć PGObject aby zapewnić mapowanie typu PgJDBC dla twojego typu. Prawdopodobnie będziesz musiał również zaimplementować procedurę obsługi typu specyficznego dla ORM, aby użyć swojego PGObject , ponieważ większość ORM-ów po prostu wywoła toString na typach, których nie rozpoznają. Jest to preferowany sposób mapowania złożonych typów między Javą i PostgreSQL, ale także najbardziej złożony.

PgJDBC:Procedura obsługi typu za pomocą setObject(int, Object)

Jeśli używasz String aby przechowywać wartość w Javie, a nie bardziej konkretny typ, możesz wywołać metodę JDBC setObject(integer, Object) do przechowywania ciągu bez określonego typu danych. Sterownik JDBC wyśle ​​reprezentację ciągu, a baza danych wywnioskuje typ z docelowego typu kolumny lub typu argumentu funkcji.

Zobacz także

Pytania:

  • Mapowanie kolumny postgreSQL JSON na typ wartości Hibernate
  • Czy możliwe są niestandardowe typy JPA (EclipseLink)?

Zewnętrzne:

  • http://www.postgresql.org/identyfikator-wiadomości/[email protected]
  • https://github.com/pgjdbc/pgjdbc/issues/265
  • http://www.pateldenish.com/2013/05/inserting-json-data-into-postgres-using-jdbc-driver.html



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Automatyzacja audytów bezpieczeństwa dla PostgreSQL

  2. Zatrzymać (długo) wykonywanie zapytania SQL w PostgreSQL, gdy sesja lub żądania już nie istnieją?

  3. Weryfikowanie kopii zapasowych PostgreSQL w Docker

  4. Wyliczenia Java, JPA i Postgres — jak sprawić, by ze sobą współpracowały?

  5. java.lang.NoSuchFieldError:BRAK w trybie hibernacji przy użyciu Spring 3, maven, JPA, c3p0