sql >> Database teknologi >  >> RDS >> PostgreSQL

Tæller Postgresql varchar ved hjælp af unicode-tegnlængde eller ASCII-tegnlængde?

Længdegrænsen pålagt af varchar(N) typer og beregnet efter length funktion er i tegn, ikke bytes. Så 'abcdef'::char(3) er afkortet til 'abc' men 'a€cdef'::char(3) er afkortet til 'a€c' , selv i sammenhæng med en database kodet som UTF-8, hvor 'a€c' er kodet med 5 bytes.

Hvis gendannelse af en dump-fil klagede over, at 'Mér' ville ikke gå ind i en varchar(3) kolonne, der tyder på, at du gendannet en UTF-8-kodet dumpfil i en SQL_ASCII-database.

For eksempel gjorde jeg dette i en UTF-8-database:

create schema so4249745;
create table so4249745.t(key varchar(3) primary key);
insert into so4249745.t values('Mér');

Og så dumpede dette og forsøgte at indlæse det i en SQL_ASCII-database:

pg_dump -f dump.sql --schema=so4249745 --table=t
createdb -E SQL_ASCII -T template0 enctest
psql -f dump.sql enctest

Og helt sikkert:

psql:dump.sql:34: ERROR:  value too long for type character varying(3)
CONTEXT:  COPY t, line 1, column key: "Mér"

Hvis jeg derimod opretter databasen enctest som encoding LATIN1 eller UTF8, indlæses den fint.

Dette problem opstår på grund af en kombination af at dumpe en database med en multi-byte tegnkodning og forsøge at gendanne den i en SQL_ASCII database. Brug af SQL_ASCII deaktiverer grundlæggende omkodningen af ​​klientdata til serverdata og antager en byte pr. tegn, hvilket overlader det til klienterne at tage ansvaret for at bruge det rigtige tegnkort. Da dump-filen indeholder den lagrede streng som UTF-8, det vil sige fire bytes, så en SQL_ASCII-database ser det som fire tegn og betragter det derfor som værende i strid med begrænsningen. Og den udskriver værdien, som min terminal derefter samler igen som tre tegn.



  1. Hvordan kan jeg fremskynde MySQL-forespørgsel med flere joinforbindelser

  2. bedste måde at konvertere og validere en datostreng

  3. Simple Express-program til forespørgsel efter et resultat

  4. Konverter tekst til Varchar