sql >> Database >  >> RDS >> PostgreSQL

Het opslaan van json, jsonb, hstore, xml, enum, ipaddr, etc mislukt met kolom x is van het type json, maar de expressie is van het type karakter variërend

Waarom het gebeurt

Het probleem is dat PostgreSQL te streng is wat betreft casts tussen tekst- en niet-tekstgegevenstypen. Het staat geen impliciete cast toe (een zonder een CAST of :: in de SQL) van een teksttype zoals text of varchar (character varying ) naar een tekstachtig niet-teksttype zoals json , xml , enz.

Het PgJDBC-stuurprogramma specificeert het gegevenstype van varchar wanneer je setString . aanroept om een ​​parameter toe te wijzen. Als het databasetype van de kolom, het functieargument, enz. in feite niet varchar is of text , maar in plaats daarvan een ander type, krijg je een typefout. Dit geldt ook voor heel wat andere stuurprogramma's en ORM's.

PgJDBC:stringtype=unspecified

De beste optie bij het gebruik van PgJDBC is over het algemeen om de parameter stringtype=unspecified door te geven . Dit overschrijft het standaardgedrag van het doorgeven van setString waarden als varchar en laat het in plaats daarvan aan de database over om hun gegevenstype te "raden". In bijna alle gevallen doet dit precies wat je wilt, de string doorgeven aan de invoervalidator voor het type dat je wilt opslaan.

Alle:CREATE CAST ... WITH FUNCTION ...

U kunt in plaats daarvan CREATE CAST om een ​​datatype-specifieke cast te definiëren om dit per type mogelijk te maken, maar dit kan elders bijwerkingen hebben. Als je dit doet, doe dan niet gebruik WITHOUT FUNCTION casts, zullen ze typevalidatie omzeilen en resulteren in fouten. U moet de invoer-/validatiefunctie voor het gegevenstype gebruiken. CREATE CAST gebruiken is geschikt voor gebruikers van andere databasestuurprogramma's die geen manier hebben om te voorkomen dat het stuurprogramma het type voor tekenreeks-/tekstparameters specificeert.

bijv.

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;

Alle:handler voor aangepast type

Als uw ORM het toelaat, kunt u een aangepaste typehandler implementeren voor het gegevenstype en die specifieke ORM. Dit is vooral handig wanneer u het native Java-type gebruikt dat goed overeenkomt met het PostgreSQL-type, in plaats van String , hoewel het ook kan werken als je ORM je type-handlers laat specificeren met behulp van annotaties enz.

Methoden voor het implementeren van aangepaste type-handlers zijn specifiek voor stuurprogramma's, talen en ORM's. Hier is een voorbeeld voor Java en Hibernate voor json .

PgJDBC:type handler met behulp van PGObject

Als u een native Java-type in Java gebruikt, kunt u PGObject . uitbreiden om een ​​PgJDBC-typetoewijzing voor uw type te bieden. U zult waarschijnlijk ook een ORM-specifieke type-handler moeten implementeren om uw PGObject te gebruiken. , aangezien de meeste ORM's gewoon toString aanroepen op typen die ze niet herkennen. Dit is de geprefereerde manier om complexe typen tussen Java en PostgreSQL in kaart te brengen, maar ook de meest complexe.

PgJDBC:Type-handler met behulp van setObject(int, Object)

Als je String . gebruikt om de waarde in Java vast te houden, in plaats van een specifieker type, kunt u de JDBC-methode setObject(integer, Object) aanroepen om de tekenreeks op te slaan zonder dat er een bepaald gegevenstype is opgegeven. Het JDBC-stuurprogramma verzendt de tekenreeksrepresentatie en de database leidt het type af van het doelkolomtype of het functieargumenttype.

Zie ook

Vragen:

  • PostgreSQL JSON-kolom toewijzen aan waardetype Slaapstand
  • Zijn JPA (EclipseLink) aangepaste typen mogelijk?

Extern:

  • http://www.postgresql.org/message-id/[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. Wat is het verschil tussen `->>` en `->` in Postgres SQL?

  2. Hoe parallelle plannen opstarten - deel 4

  3. Een samengestelde externe sleutel maken in SQL Server (T-SQL-voorbeeld)

  4. Hoe kan ik kolommen in MySQL vertragen?