# 2200C — invalid_use_of_escape_character

> PostgreSQL SQLSTATE 2200C 的来源与诊断参考。
---

# 2200C

## 速览 {#at-a-glance}
检查完整报文和实际 SQL `SIMILAR TO` 模式；18.6 的 `regexp.c` 路径会在翻译阶段报告 `SQL regular expression may not contain more than two escape-double-quote separators`。这里针对的是 SQL 到 POSIX 正则的翻译语法，不是一般 POSIX 反斜杠转义。

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `2200C` |
| 条件名 | `invalid_use_of_escape_character` |
| 状态 | `有效` |
| 已知存在于 | `7.4` |
| 锁定快照 | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| 宏 | `ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER` |
| 别名 | `—` |

<!-- source facts: data/errcodes/2200C.json -->
<!-- END SQLSTATE FACTS -->

## 含义 {#meaning}
本条件属于数据异常族，表示 PostgreSQL 将 SQL `SIMILAR TO` 模式翻译为 POSIX 正则形式时拒绝了转义结构。`similar_escape_internal` 在方括号表达式之外把带转义的双引号视为 SQL `SUBSTRING` 三段之间的分隔符；第三个分隔符会被拒绝。同一 helper 也服务于 `SIMILAR TO` 翻译，在普通匹配中这些分隔符不改变匹配行为。

## 报文 {#messages}

已确认的 guard 以 `ERROR` 严重性报告 primary：`SQL regular expression may not contain more than two escape-double-quote separators`；该分支没有独立 DETAIL 或 HINT。无效 `ESCAPE` 字符串属于其他 SQLSTATE 路径，应保留实际报文和代码。

## 诊断 {#diagnosis}
这是解析器和输入的问题，应分别检查 SQL 字符串层、`SIMILAR TO` 模式和 `ESCAPE` 字符。统计方括号表达式之外的转义双引号分隔符，并确认操作是 `SIMILAR TO` 还是 `SUBSTRING ... SIMILAR`；不能把正则中的每个反斜杠都诊断为 2200C。

## 处理 {#response}
按预期的 `SIMILAR TO`/`SUBSTRING` 语义修正 SQL 模式或 `ESCAPE` 表示，确认分隔符数量后再执行；不要无条件增删 POSIX 反斜杠。

该分支抛出 `ERROR` 时，显式事务应先用 `ROLLBACK` 恢复，或对语句前已建立的保存点执行 `ROLLBACK TO SAVEPOINT`，再重试；自动提交下只在失败语句结束后重试修正后的动作。事务边界规则见[事务与重试指南](../guides/)。

## 版本 {#versions}
锁定目录从 7.4 起记录该条件；固定源码覆盖 PostgreSQL 18.6。

## 相关 {#related}
[`2200D`](../2200d/)、[`22000`](../22000/)

## 来源 {#sources}
固定源码：[`src/backend/utils/adt/regexp.c#L758-951`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/regexp.c#L758-L951)。结构化[证据记录](../../data/evidence/2200c.json)保留定义、消息和范围边界。该路径是 PostgreSQL 的 SQL `SIMILAR TO` 翻译 helper；本页未运行自然案例。其他转义失败应按实际 SQLSTATE 和报文判断。
