我知道这个错误消息的含义Value too long for character type character varying(100)
。因此,我经常寻找导致问题的行,并根据要求适当地修复它们。
但我今天遇到了一个奇怪的问题,即使没有粗行,也会发生错误。
插入查询失败:
INSERT INTO training.archive_temp1 (id, booking, email, pcd_temp, property_id)
WITH x_pcd AS (
SELECT e.id,
e.booking,
e.email,
CASE
WHEN LENGTH(e.pch) > 0 THEN (e.pch || ':' || e.pcd)
ELSE e.pcd
END AS pcd_temp,
e.pcd
FROM public.extracts_temp AS e WHERE e.id BETWEEN 274939128 AND 275083166
)
SELECT x.id,
x.booking,
x.email,
x.pcd_temp,
COALESCE(c2.property_id, c.property_id)
FROM x_pcd AS x
LEFT JOIN public.property_codes AS c ON x.pcd_temp = c.code
LEFT JOIN public.property_codes AS c2 ON x.pcd = c2.code
WHERE COALESCE(c2.property_id,c.property_id, 0) <> 0;
Run Code Online (Sandbox Code Playgroud)
如果我改x.email
一下x.email::varchar(100)
就可以了。
这就是问题所在。
SELECT max(length(email)) FROM training.archive_temp1;
-- returns 64
Run Code Online (Sandbox Code Playgroud)
诡异的。所以我检查了
SELECT max(length(email)) FROM (
SELECT e.id,
e.booking,
e.email,
CASE
WHEN LENGTH(e.pch) > 0 THEN (e.pch || ':' || e.pcd)
ELSE e.pcd
END AS pcd_temp,
e.pcd
FROM public.extracts_temp AS e WHERE e.id BETWEEN 274939128 AND 275083166
)
-- returns 66
Run Code Online (Sandbox Code Playgroud)
如果没有行超过 100 个字符限制,为什么会抛出错误?这里发生了什么?
如果您需要我分享您的任何疑问的结果,请告诉我。由于行数在 100000 范围内,因此无法在此处共享整个数据,并且如果我可以共享该案例的最小可验证示例,我就不会问这个问题。
Redshift 可以将多字节字符串存储到 varchar 字段中。但如果你定义你的字段,varchar(100)
它并不意味着 100 个字符。相反,它意味着 100 个字节。因此,如果字符串中的所有字符都是两个字节字符,则该字段最多可以存储 50 个字符。
从文档来看,
使用 VARCHAR 或 CHARACTER VARYING 列存储具有固定限制的可变长度字符串。这些字符串不会用空格填充,因此 VARCHAR(120) 列最多包含 120 个单字节字符、60 个两字节字符、40 个三字节字符或 30 个四字节字符。
问题是LENGTH
函数仅返回字符数,而不返回不包括尾随空格的字节数。因此,获取多字节字符的长度仅返回 1。此处对此进行了记录。
替代的OCTET_LENGTH可以返回字节数而不是字符数。
运行 OCTET_LENGTH 发现麻烦制造者,现已修复。
归档时间: |
|
查看次数: |
24599 次 |
最近记录: |