PostgreSQL使用E'xxx'语法时需转义哪些字符?是否有对应正式BNF文档?
核心结论
$$这类美元引号包裹的dollar-quoted字符串,本身不存在需要针对花括号等特殊字符强制转义的规则,之前把“未闭合”报错归因到花括号是错误的定位。
正式解析规则
按照PostgreSQL的语法定义,dollar-quoted字符串的解析逻辑非常明确:
- 字符串以格式为
$<可选自定义标签>$的标记作为起始边界,只有当文本中出现和起始标记完全一模一样的序列时,才会判定字符串结束。 - 全解析过程不会因为任何其他特殊字符调整字符串边界:不管是花括号、单引号、括号、反斜杠、其他可打印符号,全都会被当作普通文本处理,没有任何必须额外转义的字符。
- 你使用的无标签dollar引号
$$,按照规则,只有当块内部完整出现连续的$$序列时,才会打断外层的dollar字符串;单个的$、附带其他字符的$xxx$序列,都不会触发闭合判定。
之前报错的真实触发原因
你观察到的“出现花括号就触发$$未闭合”只是表面巧合,真实的报错触发点是花括号附近刚好存在符合dollar标签格式的截断序列:
- 最高发的场景:字符串值里无意中写了连续两个美元符号,凑成了和外层一致的
$$序列,直接截断了外层DO块的dollar字符串 - 如果用的是带自定义标签的dollar引号(比如
$do_block$),则是字符串值里刚好出现了和标签完全匹配的$do_block$序列
单独书写单个{、},完全不可能触发$$未闭合的报错。
之前转义操作生效的本质
你用\x7B/\x7D替换花括号后问题消失,并不是因为花括号需要转义:替换字符的过程刚好把卡在花括号位置、真正会截断dollar字符串的连续$$序列给替换掉了,从根源上消掉了触发报错的截断点。
转义边界的实际使用说明
- 外层dollar块包裹的整段代码里,所有不构成边界匹配序列的普通字符,都不需要转义,直接写花括号、单引号、反斜杠都可以正常解析
- 只有在dollar块内部、由单引号(包括E开头的转义单引号)界定的字符串值里,才需要按照转义字符串的规则处理对应特殊字符,这部分逻辑和外层的dollar引号没有任何关联。
内容的提问来源于stack exchange,提问作者Ivan Cruz
相关产品推荐
相关产品推荐

