← 返回错误码列表

MySQL错误码 1022 分析与解决方案

错误信息

Error 1022

无法写入;重复键。检查唯一约束。

你的PHP应用在使用PDO连接MySQL时遇到了重复键错误:

'pdo_code' => '23000',
'db_code' => 1022,
'db_error' => 'Can\'t write; duplicate key in table'

解决方案

  • 检查并确保插入的数据不违反唯一约束
  • 使用 INSERT IGNORE 忽略重复键错误
  • 使用 ON DUPLICATE KEY UPDATE 更新已存在记录
  • 使用 REPLACE INTO 替换已存在记录
  • 先查询是否存在再决定插入或更新
  • 检查业务逻辑确保数据唯一性

PHP处理重复键示例代码

// 方法1: 使用 INSERT IGNORE
$sql = "INSERT IGNORE INTO users (username, email) VALUES (?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$username, $email]);
$affectedRows = $stmt->rowCount();

// 方法2: 使用 ON DUPLICATE KEY UPDATE
$sql = "INSERT INTO users (username, email, last_login) "
        . "VALUES (?, ?, NOW()) "
        . "ON DUPLICATE KEY UPDATE last_login = NOW()";
$stmt = $pdo->prepare($sql);
$stmt->execute([$username, $email]);

// 方法3: 先检查后操作
$checkSql = "SELECT COUNT(*) FROM users WHERE username = ?";
$checkStmt = $pdo->prepare($checkSql);
$checkStmt->execute([$username]);
$exists = $checkStmt->fetchColumn() > 0;

if ($exists) {
  // 更新现有记录
  $updateSql = "UPDATE users SET email = ?, last_login = NOW() WHERE username = ?";
  $updateStmt = $pdo->prepare($updateSql);
  $updateStmt->execute([$email, $username]);
} else {
  // 插入新记录
  $insertSql = "INSERT INTO users (username, email) VALUES (?, ?)";
  $insertStmt = $pdo->prepare($insertSql);
  $insertStmt->execute([$username, $email]);
}

重复键错误模拟演示

重复键错误通常发生在尝试插入违反唯一约束的数据时:

用户表结构

唯一约束:username 字段

现有用户:john_doe

尝试插入重复数据

INSERT INTO users (username, email) VALUES ('john_doe', 'john@example.com')

违反唯一约束 → 错误 1022

解决方案

使用 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE

或者先检查用户名是否已存在

预防措施

1. 数据库设计

  • 合理设置唯一约束和主键
  • 使用复合唯一键确保业务数据完整性
  • 考虑使用UUID代替自增ID避免冲突

2. 应用层处理

  • 实现数据验证和去重逻辑
  • 使用事务确保数据一致性
  • 实现适当的错误处理机制

3. 批量操作优化

  • 使用LOAD DATA INFILE处理大量数据
  • 分批处理避免单次操作数据量过大
  • 使用INSERT ... SELECT语法

调试工具

使用以下MySQL命令分析唯一约束:

# 查看表的索引和约束信息
SHOW INDEX FROM table_name;

# 查看表结构
DESCRIBE table_name;

# 查看创建表的SQL语句
SHOW CREATE TABLE table_name;

重复键分析要点

检查以下内容:

  • 哪些字段有唯一约束
  • 插入的数据是否与现有数据冲突
  • 业务逻辑是否需要调整
  • 是否可以使用UPSERT操作