PostgreSQL字符串解析报错:期望'('或UNNEST却得到标识符
问题分析与解决
错误原因
你写的SQL语句报错,核心问题出在substring函数的for子句表达式上:
- 首先是逻辑错误:你计算长度的公式完全搞反了。
Call ID:的长度是8个字符,要提取的内容是从Call ID:结束的位置(position('Call ID:' in body)+8)到Interaction ID:开始的位置,所以正确的长度应该是position('Interaction ID:' in body) - (position('Call ID:' in body) + 8),而你写成了position('Interaction ID:' in body)- position('Call ID:' in body)+8,这会导致长度计算值异常,甚至出现负数。 - 其次,PostgreSQL对
substring(string from start for length)的length参数要求是非负整数,如果你的表达式计算出负数,或者因优先级问题(缺少括号)导致解析器误判为标识符,就会触发你看到的语法错误。
正确写法(推荐正则表达式方式)
相比手动计算位置,用正则表达式提取更简洁、健壮,能避免位置计算的各种异常:
SELECT id, substring(body FROM 'Call ID: (.*?) Interaction ID:') AS Call_id FROM Table_T;
说明
'Call ID: (.*?) Interaction ID:'是正则表达式,其中(.*?)是非贪婪匹配,会精准提取Call ID:和Interaction ID:之间的内容,不管中间内容长度多少。- 如果某行
body不包含指定格式的文本,substring会返回NULL,不会触发错误。
修正原写法(不推荐,仅作参考)
如果你坚持用位置计算的方式,需要修正长度的计算公式:
SELECT id, substring(body from position('Call ID:' in body) + 8 for position('Interaction ID:' in body) - (position('Call ID:' in body) + 8)) FROM Table_T;
注意
这种写法有局限性:如果body中缺少Call ID:或Interaction ID:,position会返回0,计算出的起始位置或长度会无效,可能导致报错或提取错误内容。
内容的提问来源于stack exchange,提问作者Phil C.
相关产品推荐
相关产品推荐

