ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PostgreSQL 字符串中的单引号转义:`‘‘` 双写、`E` 前缀与美元引用详解

PostgreSQL 字符串中的单引号转义:`‘‘` 双写、`E` 前缀与美元引用详解 文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载在 PostgreSQL 中varchar和text等字符串字面量一律使用单引号包裹这就带来了一个绕不开的问题当字符串内容本身包含单引号时该如何书写本指南以 postgres/escaping-a-quote-in-a-string.md 为核心完整讲解最基础的单引号转义规则并结合本仓库中同主题的 TIL 笔记扩展出E前缀转义、美元引用dollar quoting与带标签美元引用三种替代方案。读完本文你将能在 psql 交互环境与程序化生成的 SQL 中从容处理任何包含单引号、甚至包含$$序列的字符串字面量。为什么单引号必须被转义字符串字面量的定界符就是单引号本身。PostgreSQL 在解析select whats up!;时需要区分作为定界符的单引号和作为内容的单引号。如果不做任何处理直接写出whats up!解析器会把what当作完整字符串随后s up!变成游离文本最终因找不到配对的定界符而报语法错误。PostgreSQL 官方给出的转义规则非常朴素字符串字面量内部的单引号用另一个单引号来转义。也就是说把写成两个连续的单引号中第一个让第二个脱去定界符身份从而作为字符内容出现在最终字符串中。方法一双单引号转义核心写法这是原文档给出的、也是 PostgreSQL 语义最标准、与standard_conforming_strings行为无关的写法。在 psql 中直接验证 select whats up!; ?column? ------------ whats up!解析过程可以这样理解字面量以第一个开始随后遇到两个连续单引号它们被整体解释为一个内容字符最后一个负责收尾。本仓库的姊妹笔记 postgres/two-ways-to-escape-a-quote-in-a-string.md 用whos on first?展示了同一个要点 select whos on first?; ?column? ----------------- whos on first? (1 row)双单引号写法的最大优点是无条件可用无论会话级配置standard_conforming_strings如何设置它都按固定规则解析不依赖任何上下文开关。缺点同样明显——当字符串中单引号密集出现时肉眼很难数清引号配对的层级例如同时包含its、Johns的文本会写成一长串阅读与维护成本较高。常见的失败形态未转义时的表现把单引号直接塞进字符串而不做任何处理查询不会报出明确的错误而是表现为语句迟迟不结束。原因在于 psql 认为字符串还没有闭合会持续等待你输入闭合引号 select whos on first?; ...正如 postgres/two-ways-to-escape-a-quote-in-a-string.md 所描述的这条查询不会执行因为它正在等待你关闭第二组引号。遇到这种悬挂在续行状态的输入可以按Ctrl-C中断再补上转义后重新提交。方法二E前缀 反斜杠转义除了双写单引号postgres/two-ways-to-escape-a-quote-in-a-string.md 还记录了第二种思路给字符串字面量加上E前缀使反斜杠转义序列escape sequence在字符串内生效 select Ewho\s on first?; ?column? ----------------- whos on first? (1 row)这里E...让 PostgreSQL 以转义字符串的语义解析字面量于是\被解释为单个单引号字符。需要注意在现代 PostgreSQL 中standard_conforming_strings默认开启普通字符串不带E前缀中的反斜杠会被当作普通字符处理此时who\s on first?不会得到你想要的结果只有显式添加E前缀后反斜杠才具备转义能力。因此E前缀写法适合你确实想用反斜杠体系管理特殊字符的场景日常写包含单引号的普通文本时双单引号更直接。方法三美元引用Dollar Quoting双单引号易出错、且在程序化生成 SQL 时不好用这是本仓库另一篇笔记 postgres/escaping-string-literals-with-dollar-quoting.md 提出的核心痛点。它的解决方案是用$$取代作为定界符 select $$Isnt this even nicer?$$; ?column? ------------------------ Isnt this even nicer?用法就是把两端的换成$$字符串内部的单引号不再需要任何转义。这对两类场景尤其有价值动态拼接 SQL在应用代码里用字符串模板拼 SQL 时双单引号要求拼装逻辑额外感知内容中的引号美元引用让内容原样穿过拼接层。定义函数/存储过程体函数体内部几乎必然出现字符串与引号用$$...$$包裹 PL/pgSQL 函数体是 PostgreSQL 社区最常见的写法。进阶带标签的美元引用如果字符串内容里碰巧出现了连续两个$符号比如价格文本$$$裸$$定界符也会冲突。此时可用带标签的美元引用。仓库笔记 postgres/label-dollar-quoted-strings-with-a-tag.md 给出了非常直观的 JSON 示例 select $JSON${name: Sallys Bistro, price: $$$}$JSON$::jsonb; jsonb -------------------------------------------- {name: Sallys Bistro, price: $$$} (1 row) select $JSON${name: Sallys Bistro, price: $$$}$JSON$-name as name; name ------------------ Sallys Bistro (1 row)这段笔记的要点有三个标签放在两对$之间本例标签为JSON写作$JSON$ ... $JSON$既能避开内容中的$$又能向读者传达这段字面量代表 JSON的语义信息标签命名规则标签遵循与未加引号标识符相同的规则唯一例外是不能包含美元符号标签区分大小写$JSON$与$json$是不同的定界符书写时需保持一致。借助带标签美元引用第一段 SQL 把整段 JSON 文本内含单引号Sallys与双美元$$$直接转型为jsonb而无需思考任何字符需要转义第二段则进一步证明转型后的值可以像普通jsonb实体一样使用-运算符访问字段。四种方案如何选择方案写法示例适用场景注意点双单引号whats up!手写少量含单引号的文本引号密集时可读性差E前缀Ewho\s on first?需要反斜杠转义体系依赖E前缀显式开启转义语义裸美元引用$$Isnt this nicer?$$程序化生成 SQL、函数体内容含$$时会冲突带标签美元引用$JSON${...}$JSON$内容含$$或想表达语义标签不能含$且区分大小写仓库延伸阅读围绕字符串与引号这一主题本仓库的 postgres 目录下还有以下可直接对照的 TIL 笔记postgres/escaping-a-quote-in-a-string.md本文核心——双单引号转义postgres/two-ways-to-escape-a-quote-in-a-string.md与E前缀两种方式对照postgres/escaping-string-literals-with-dollar-quoting.md$$美元引用入门postgres/label-dollar-quoted-strings-with-a-tag.md带标签美元引用处理含$$的内容。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐TIL 实战PostgreSQL 字符串中单引号的两种转义方式双写引号与 E 转义字符串TIL 实战PostgreSQL 字符串中单引号的两种转义方式双写引号与 E 转义字符串 在 PostgreSQL 中字符串字面量必须用单引号 文档教程知识库xonsh 子进程字符串完全指南Python 语义、引号规则与字符串前缀实战xonsh 子进程字符串完全指南Python 语义、引号规则与字符串前缀实战 本篇技术指南聚焦 xonshPython powered shell在 子进开发工具Hugo 模板中的 Interpreted String Literal双引号字符串的转义语义与实战指南Hugo 模板中的 Interpreted String Literal双引号字符串的转义语义与实战指南 导读 interpreted string lite开发工具前端CLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表