목차
回复内容:
백엔드 개발 PHP 튜토리얼 [Mysql] Select 不到,Insert出错的问题,字段编码问题

[Mysql] Select 不到,Insert出错的问题,字段编码问题

Jun 06, 2016 pm 08:49 PM
linux mysql php

Mysql 5.5 表结构为:

<code>CREATE TABLE `account` (
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
</code>
로그인 후 복사
로그인 후 복사

name 字段目前的编码:

<code>CharacterSet:gbk
Collation:gbk_chinese_ci
</code>
로그인 후 복사
로그인 후 복사

目前我的程序逻辑为:

首先:

<code>select * from `account` where `name`=?
</code>
로그인 후 복사
로그인 후 복사

如果返回空,则插入该name:

<code>insert into `account` (`name`) values(?)
</code>
로그인 후 복사
로그인 후 복사

现在在我后台有几个报错记录:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Duplicate entry '积分' for key 'PRIMARY'

(请忽略name为乱码,这可能是我输出记录文本导致的)

我的问题是,为什么我明明先select了该name,没有我才会insert,还会导致这个异常?

这是否跟我设置了name字段为gbk编码有关?有没相关参考文章可以提供给我看下?

应该将该字段编码设置为什么来避免这个问题?

BTW:使用ignore参数当然可以忽略该异常,但我主要想知道为什么之前select无法获取,Insert却出错

回复内容:

Mysql 5.5 表结构为:

<code>CREATE TABLE `account` (
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
</code>
로그인 후 복사
로그인 후 복사

name 字段目前的编码:

<code>CharacterSet:gbk
Collation:gbk_chinese_ci
</code>
로그인 후 복사
로그인 후 복사

目前我的程序逻辑为:

首先:

<code>select * from `account` where `name`=?
</code>
로그인 후 복사
로그인 후 복사

如果返回空,则插入该name:

<code>insert into `account` (`name`) values(?)
</code>
로그인 후 복사
로그인 후 복사

现在在我后台有几个报错记录:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Duplicate entry '积分' for key 'PRIMARY'

(请忽略name为乱码,这可能是我输出记录文本导致的)

我的问题是,为什么我明明先select了该name,没有我才会insert,还会导致这个异常?

这是否跟我设置了name字段为gbk编码有关?有没相关参考文章可以提供给我看下?

应该将该字段编码设置为什么来避免这个问题?

BTW:使用ignore参数当然可以忽略该异常,但我主要想知道为什么之前select无法获取,Insert却出错

字符编码问题请高人来解答。

我只说点别的。

在高并发的情况下,你这两次操作的结果是不确定的,是不安全的。

使用如下的原子操作更安全一些。

<code>INSERT INTO `table` (`id`, `name`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`);
</code>
로그인 후 복사

或者

<code>INSERT IGNORE INTO `table` (`id`, `name`) VALUES (?, ?)
</code>
로그인 후 복사

个人认为这应该不是编码问题, 而是象 @HJin.me 所说, 是一个并发问题. 即session1 在select 得到empty set后; session2 去insert了一个相同的name; 此时session1去 insert, 则得到 duplicated.

mysql事务默认的隔离级别是repeated read, 不会防止上面的情况, 实验一把.

<code>session1:  start transaction;
session2:  start transaction;
session1:  select * from account where name='11'; //empty set
session2:  insert into account values('11');
session2:  commit;
session1:  insert into account values('11'); // duplicate key
</code>
로그인 후 복사
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

뜨거운 기사 태그

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드

DeepSeek 웹 버전 입구 DeepSeek 공식 웹 사이트 입구 DeepSeek 웹 버전 입구 DeepSeek 공식 웹 사이트 입구 Feb 19, 2025 pm 04:54 PM

DeepSeek 웹 버전 입구 DeepSeek 공식 웹 사이트 입구

DeepSeek을 설치하는 방법 DeepSeek을 설치하는 방법 Feb 19, 2025 pm 05:48 PM

DeepSeek을 설치하는 방법

MySQL 8.4에서 mysql_native_password가 로드되지 않음 오류를 수정하는 방법 MySQL 8.4에서 mysql_native_password가 로드되지 않음 오류를 수정하는 방법 Dec 09, 2024 am 11:42 AM

MySQL 8.4에서 mysql_native_password가 로드되지 않음 오류를 수정하는 방법

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법

PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? Feb 07, 2025 am 11:57 AM

PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까?

문자열로 모음을 계산하는 PHP 프로그램 문자열로 모음을 계산하는 PHP 프로그램 Feb 07, 2025 pm 12:12 PM

문자열로 모음을 계산하는 PHP 프로그램

Bitget 공식 웹 사이트 설치 (2025 초보자 안내서) Bitget 공식 웹 사이트 설치 (2025 초보자 안내서) Feb 21, 2025 pm 08:42 PM

Bitget 공식 웹 사이트 설치 (2025 초보자 안내서)

See all articles