Ben*_*tin 21 postgresql unicode
我尝试从SQL文件导入数据库转储,并且在将字符串Mér插入定义为的字段时插入失败varying(3).我没有捕获确切的错误,但它指出了具有约束的特定值varying(3).
鉴于我认为这对我当时正在做的事情不重要,我只是改变了价值Mer,它运作了,我继续前进.
varying考虑到字节字符串长度的字段是否有限制?令我难以置信的是,这是从另一个PostgreSQL数据库转储的.因此,约束如何允许最初写入值是没有意义的.
ara*_*nid 32
由varchar(N)类型强加并由length函数计算的长度限制是字符,而不是字节.因此'abcdef'::char(3)被截断为'abc'但'a€cdef'::char(3)被截断为'a€c',即使在编码为UTF-8的数据库的上下文中,'a€c'也使用5个字节进行编码.
如果恢复转储文件抱怨'Mér'不会进入varchar(3)列,则表明您正在将UTF-8编码的转储文件还原到SQL_ASCII数据库中.
例如,我在UTF-8数据库中执行此操作:
create schema so4249745;
create table so4249745.t(key varchar(3) primary key);
insert into so4249745.t values('Mér');
Run Code Online (Sandbox Code Playgroud)
然后将其转储并尝试将其加载到SQL_ASCII数据库中:
pg_dump -f dump.sql --schema=so4249745 --table=t
createdb -E SQL_ASCII -T template0 enctest
psql -f dump.sql enctest
Run Code Online (Sandbox Code Playgroud)
果然:
psql:dump.sql:34: ERROR: value too long for type character varying(3)
CONTEXT: COPY t, line 1, column key: "Mér"
Run Code Online (Sandbox Code Playgroud)
相比之下,如果我创建数据库enctest作为编码LATIN1或UTF8,它加载正常.
出现此问题的原因是将数据库转储为多字节字符编码,并尝试将其还原到SQL_ASCII数据库中.使用SQL_ASCII基本上禁止将客户端数据转码为服务器数据,并假定每个字符占一个字节,让客户端负责使用正确的字符映射.由于转储文件包含存储的字符串为UTF-8,即四个字节,因此SQL_ASCII数据库将其视为四个字符,因此将其视为违反约束.它打印出值,然后我的终端重新组装为三个字符.
小智 5
这取决于您在创建数据库时使用的值。createdb -E UNICODE创建一个 Unicode DB,它也应该接受多字节字符并将它们算作一个字符。
您可以使用
psql -l
Run Code Online (Sandbox Code Playgroud)
查看使用了哪种编码。 此页面有一个表格,其中包含有关每个字符使用多少字节的信息。
| 归档时间: |
|
| 查看次数: |
13181 次 |
| 最近记录: |