# 27000 — triggered_data_change_violation（触发的数据更改违规）

> PostgreSQL SQLSTATE 27000 的来源与机制边界参考。
---

# 27000 — triggered_data_change_violation（触发的数据更改违规）

## 速览 {#at-a-glance}

`27000` 是源码确认的触发器保护条件。当当前命令触发的操作已经修改某行时，PostgreSQL 会使用这个码；18.6 固定源码的提示建议在需要向其他行传播变化时考虑 AFTER trigger。简单的“自身更新” BEFORE trigger 可能递归或改变触发器语义，因此本页不把它伪装成通用安全复现。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `27000` |
| 条件名 | `triggered_data_change_violation` |
| 状态 | `有效` |
| 已知存在于 | `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_TRIGGERED_DATA_CHANGE_VIOLATION` |
| 别名 | `—` |

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

## 含义 {#meaning}

`27000` 是执行器在“当前命令触发的操作已经修改过该元组”时发出的触发数据更改违规。固定的 `trigger.c` 路径针对同一命令、同一元组的触发器改写保护；它不是所有触发器异常或递归触发器的统称。

## 诊断 {#diagnosis}

先确认目标表、命令影响的行以及可能再次更新该行的 `BEFORE` 行级触发器。固定主模板是 `tuple to be updated was already modified by an operation triggered by the current command`，提示可考虑用 `AFTER` 触发器向其他行传播变化。只会递归的自更新测试属于另一种故障，不能证明这条路径。本批没有自然运行观察；若线上真实触发，应同时保存客户端实际事务状态。

## 处理 {#response}

如果触发器是在向其他行传播变化，符合语义时可以改用 `AFTER` 触发器或一次集合式语句；若同一元组确实被两次命中，应重新设计触发器。不能套用通用重试或 `CASCADE`，也不能把人为构造的自更新递归说成 `27000`。真实显式事务失败后，先回滚再发修复 SQL。

## 版本 {#versions}

上面的锁定事实表记录项目快照范围内的目录存在情况。固定源码证据只覆盖下面声明的路径；不能仅从定义推导精确行为引入版本或更广的运行覆盖。

## 相关 {#related}

可对照[44000 WITH CHECK OPTION 违规](../44000/)和[23514 检查约束违规](../23514/)。

## 来源 {#sources}

- [`src.errcodes.18.6`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt)（SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba`）
- [`源码路径`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/trigger.c#L3404-L3407)（SHA-256 `0a539af85b0de1a04779f92202e7bfc77d85ae6da1747ea32527c67f39084fbd`）
