2011-05-09 1 views

답변

7

LAST_INSERT_ID() 함수와 INSERT IGNORE를 확인할 수 있습니다.

INSERT IGNORE가 성공하면 기본 키가 반환됩니다. 이름에 자동 증가 기본 키와 고유 키가있는 테이블을 작성해 보겠습니다.

앞의 예와 같이
mysql> use test 
Database changed 
mysql> DROP TABLE IF EXISTS nametable; 
Query OK, 0 rows affected (0.04 sec) 

mysql> CREATE TABLE nametable 
    -> (
    -> id int not null auto_increment, 
    -> name varchar(20) not null, 
    -> primary key (id), 
    -> unique key (name) 
    ->); 
Query OK, 0 rows affected (0.07 sec) 

mysql> DELIMITER $$ 
mysql> DROP FUNCTION IF EXISTS `test`.`InsertName` $$ 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE FUNCTION `test`.`InsertName` (newname VARCHAR(20)) RETURNS INT 
    -> BEGIN 
    -> INSERT IGNORE INTO test.nametable (name) VALUES (newname); 
    -> RETURN LAST_INSERT_ID(); 
    -> END $$ 
Query OK, 0 rows affected (0.00 sec) 

mysql> DELIMITER ; 
mysql> SELECT InsertName('rolando'); 
+-----------------------+ 
| InsertName('rolando') | 
+-----------------------+ 
|      1 | 
+-----------------------+ 
1 row in set (0.03 sec) 

mysql> SELECT InsertName('rolando'); 
+-----------------------+ 
| InsertName('rolando') | 
+-----------------------+ 
|      0 | 
+-----------------------+ 
1 row in set (0.02 sec) 

mysql> SELECT InsertName('pamela'); 
+----------------------+ 
| InsertName('pamela') | 
+----------------------+ 
|     3 | 
+----------------------+ 
1 row in set (0.02 sec) 

mysql> SELECT InsertName('pamela'); 
+----------------------+ 
| InsertName('pamela') | 
+----------------------+ 
|     0 | 
+----------------------+ 
1 row in set (0.03 sec) 

mysql> SHOW CREATE TABLE test.nametable\G 
*************************** 1. row *************************** 
     Table: nametable 
Create Table: CREATE TABLE `nametable` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(20) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `name` (`name`) 
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 
1 row in set (0.00 sec) 

mysql> SELECT * FROM test.nametable; 
+----+---------+ 
| id | name | 
+----+---------+ 
| 3 | pamela | 
| 1 | rolando | 
+----+---------+ 
2 rows in set (0.00 sec) 

mysql> 

, 당신은 함수의 반환 값을 확인할 수 있습니다

use test 
DROP TABLE IF EXISTS nametable; 
CREATE TABLE nametable 
(
    id int not null auto_increment, 
    name varchar(20) not null, 
    primary key (id), 
    unique key (name) 
); 
DELIMITER $$ 
DROP FUNCTION IF EXISTS `test`.`InsertName` $$ 
CREATE FUNCTION `test`.`InsertName` (newname VARCHAR(20)) RETURNS INT 
BEGIN 
    INSERT IGNORE INTO test.nametable (name) VALUES (newname); 
    RETURN LAST_INSERT_ID(); 
END $$ 
DELIMITER ; 
SELECT InsertName('rolando'); 
SELECT InsertName('rolando'); 
SELECT InsertName('pamela'); 
SELECT InsertName('pamela'); 
SHOW CREATE TABLE test.nametable\G 
SELECT * FROM test.nametable; 

다음은 예를 들어 실행되고있다. 0이 아닌 반환 값은 INSERT IGNORE가 잘되었음을 의미합니다. 0 반환 값은 mysqld에 에러 번호를 삽입하지 않고 중복 키를 나타냅니다.

이 접근법의 단점은 중복 키가 발생한 경우 IGNORE INSERT 시도가 실패했기 때문에 돌아가서 ID 2와 4를 사용할 수 없다는 것입니다. 저장된 함수가 반환이 예에서

mysql> use test 
Database changed 
mysql> DROP TABLE IF EXISTS nametable; 
Query OK, 0 rows affected, 1 warning (0.00 sec) 

mysql> CREATE TABLE nametable 
    -> (
    -> id int not null auto_increment, 
    -> name varchar(20) not null, 
    -> primary key (id), 
    -> unique key (name) 
    ->); 
Query OK, 0 rows affected (0.10 sec) 

mysql> DELIMITER $$ 
mysql> DROP FUNCTION IF EXISTS `test`.`InsertName` $$ 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE FUNCTION `test`.`InsertName` (newname VARCHAR(20)) RETURNS INT 
    -> BEGIN 
    -> DECLARE rv INT; 
    -> SELECT COUNT(1) INTO rv FROM test.nametable WHERE name = newname; 
    -> IF rv = 0 THEN 
    ->  INSERT INTO test.nametable (name) VALUES (newname); 
    -> END IF; 
    -> RETURN rv; 
    -> END $$ 
Query OK, 0 rows affected (0.00 sec) 

mysql> DELIMITER ; 
mysql> SELECT InsertName('rolando'); 
+-----------------------+ 
| InsertName('rolando') | 
+-----------------------+ 
|      0 | 
+-----------------------+ 
1 row in set (0.04 sec) 

mysql> SELECT InsertName('rolando'); 
+-----------------------+ 
| InsertName('rolando') | 
+-----------------------+ 
|      1 | 
+-----------------------+ 
1 row in set (0.00 sec) 

mysql> SELECT InsertName('pamela'); 
+----------------------+ 
| InsertName('pamela') | 
+----------------------+ 
|     0 | 
+----------------------+ 
1 row in set (0.03 sec) 

mysql> SELECT InsertName('pamela'); 
+----------------------+ 
| InsertName('pamela') | 
+----------------------+ 
|     1 | 
+----------------------+ 
1 row in set (0.00 sec) 

mysql> SHOW CREATE TABLE test.nametable\G 
*************************** 1. row *************************** 
     Table: nametable 
Create Table: CREATE TABLE `nametable` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(20) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `name` (`name`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 
1 row in set (0.00 sec) 

mysql> SELECT * FROM test.nametable; 
+----+---------+ 
| id | name | 
+----+---------+ 
| 2 | pamela | 
| 1 | rolando | 
+----+---------+ 
2 rows in set (0.00 sec) 

mysql> 

: 여기

use test 
DROP TABLE IF EXISTS nametable; 
CREATE TABLE nametable 
(
    id int not null auto_increment, 
    name varchar(20) not null, 
    primary key (id), 
    unique key (name) 
); 
DELIMITER $$ 
DROP FUNCTION IF EXISTS `test`.`InsertName` $$ 
CREATE FUNCTION `test`.`InsertName` (newname VARCHAR(20)) RETURNS INT 
BEGIN 
    DECLARE rv INT; 
    SELECT COUNT(1) INTO rv FROM test.nametable WHERE name = newname; 
    IF rv = 0 THEN 
    INSERT INTO test.nametable (name) VALUES (newname); 
    END IF; 
    RETURN rv; 
END $$ 
DELIMITER ; 
SELECT InsertName('rolando'); 
SELECT InsertName('rolando'); 
SELECT InsertName('pamela'); 
SELECT InsertName('pamela'); 
SHOW CREATE TABLE test.nametable\G 
SELECT * FROM test.nametable; 

는 결과입니다

의이 INSERT를 사용하여 다른 저장 기능 설정으로하고 LAST_INSERT_ID()를 사용하지 않고 다른 예를 봅시다 INSERT가 OK이면 0을 반환하고 이름에 중복 키가있는 1을 반환합니다. 장점? auto_increment에 낭비되는 ID 번호가 없습니다. 단점은? 매번 SELECT 문을 사용하여 이미 테이블에있는 이름을 확인합니다.

중복 키를 처리 할 방법을 선택할 수 있습니다. 첫 번째 방법은 mysqld가 INSERT IGNORE의 조건을 처리하도록한다. 두 x 째 메소드는 INSERT 이전에 중복 키를 먼저 점검하는 스토어드 함수를 가지고 있습니다. 당신이 SPROC에 INSERT을 포함하는 경우

+0

mysql doc은 오류의 경우 LAST_INSERT_ID() 값이 정의되지 않았다고 말합니다. http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id – dancl

0

저장 프로 시저, 따라서 "모 아니면도"

, 그리고 INSERT 중복 키 오류에 실패, 전체 SPROC이 롤백됩니다.

sproc이 오류없이 실행되는 경우 INSERT에 오류가 없음을 확신 할 수 있습니다. 자,이 는 것을 의미하지 않는다 SPROC 당신이 INSERT를 제외하지만 오류가 발생하지 않는 일부 WHERE 조항이 있다면, 예를 들어 .... 오류가 없었다 단지, 완료해서 실제로 을 발생 INSERT 그러면 모호한 점이있을 수 있습니다.