수색…


통사론

  1. INSERT [LOW_PRIORITY | 지연 | HIGH_PRIORITY] [무시] [INTO] tbl_name [파티션 (partition_name, ...)] [(col_name, ...)] {VALUES | VALUE} ({expr | DEFAULT}, ...), (...), ... [중복 키 업데이트시 col_name = expr [, col_name = expr] ...]

  2. INSERT [LOW_PRIORITY | 지연 | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (파티션 이름, ...)] SET col_name = {expr | DEFAULT}, ... [중복 키 업데이트시 col_name = expr [, col_name = expr] ...]

  3. INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name, ...)] [(col_name, ...)] SELECT ... [중복 키 업데이트 col_name = expr [, col_name = expr] ...]

  4. 표현식 expr은 값 목록에서 이전에 설정된 모든 열을 참조 할 수 있습니다. 예를 들어 col2 값이 이전에 할당 된 col1을 참조하기 때문에이 작업을 수행 할 수 있습니다.
    INSERT INTO tbl_name (col1, col2) VALUES (15, col1 * 2);

  5. VALUES 구문을 사용하는 INSERT 문은 여러 행을 삽입 할 수 있습니다. 이를 수행하려면 각각 괄호 안에 쉼표로 구분 된 여러 개의 열 값 목록을 포함시킵니다. 예:
    INSERT INTO tbl_name (a, b, c) VALUES (1,2,3), (4,5,6), (7,8,9);

  6. 각 행의 값 목록은} 호로 -어야합니다. 목록의 값 수가 열 이름의 수와 일치하지 않기 때문에 다음 문은 잘못된 것입니다.
    INSERT INTO tbl_name (a, b, c) VALUES (1,2,3,4,5,6,7,8,9);

  7. INSERT ... SELECT 구문
    INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name, ...)] [(col_name, ...)] SELECT ... [중복 키 업데이트 col_name = expr, ...]

  8. INSERT ... SELECT를 사용하여 하나 이상의 테이블에서 많은 행을 테이블에 신속하게 삽입 할 수 있습니다. 예 :
    INSERT INTO tbl_temp2 (fld_id) SELECT tbl_temp1.fld_order_id FROM tbl_temp1 WHERE tbl_temp1.fld_order_id> 100;

비고

공식 INSERT 구문

기본 삽입

INSERT INTO `table_name` (`field_one`, `field_two`) VALUES ('value_one', 'value_two');

이 간단한 예제에서 table_name 은 데이터를 추가 할 위치이고, field_onefield_two 는 데이터를 설정하는 필드이고 value_onevalue_two 는 각각 field_onefield_two 에 대해 수행 할 데이터입니다.

코드를 삽입하는 필드를 코드 내에 나열하는 것이 좋습니다. 예를 들어 테이블이 변경되고 새 열이 추가되고 삽입이 끊어지면 마치 삽입되지 않습니다.

중복 키 업데이트시 INSERT

INSERT INTO `table_name` 
    (`index_field`, `other_field_1`, `other_field_2`) 
    VALUES 
    ('index_value', 'insert_value', 'other_value') 
    ON DUPLICATE KEY UPDATE 
        `other_field_1` = 'update_value',
        `other_field_2` = VALUES(`other_field_2`);

table_name 에 지정된 값을 INSERT 하지만 고유 키가 이미있는 경우 other_field_1 을 새 값으로 업데이트합니다.
때로는 중복 키를 업데이트 할 때 직접 값을 설정하는 대신 INSERT 에 전달 된 원래 값에 액세스하기 위해 VALUES() 를 사용하면 편리합니다. 이렇게하면 INSERTUPDATE 를 사용하여 다른 값을 설정할 수 있습니다. 여기서 위의 예를 참조하십시오 other_field_1 설정되어 insert_valueINSERT 하거나 update_valueUPDATE 동안 other_field_2 항상 설정되어 other_value .

IODKU (Insert on Duplicate Key Update)가 작동하려면 핵심 충돌이 있음을 알리는 고유 한 키가 포함 된 스키마가 가장 중요합니다. 이 고유 키는 기본 키가 될 수도 있고 그렇지 않을 수도 있습니다. 단일 열의 고유 키이거나 다중 열 (복합 키) 일 수 있습니다.

여러 행 삽입

INSERT INTO `my_table` (`field_1`, `field_2`) VALUES 
    ('data_1', 'data_2'),
    ('data_1', 'data_3'),
    ('data_4', 'data_5'); 

하나의 INSERT 문으로 한 번에 여러 행을 추가하는 쉬운 방법입니다.

이런 종류의 '배치'삽입은 행을 하나씩 삽입하는 것보다 훨씬 빠릅니다. 일반적으로 이러한 방식으로 단일 배치 삽입물에 100 개의 행을 삽입하면 모두 개별적으로 삽입하는 것보다 10 배 빠릅니다.

기존 행 무시하기

대형 데이터 세트를 가져올 때 특정 상황에서 대개 중복 기본 키와 같은 열 억제로 인해 쿼리가 실패하게되는 행을 건너 뛰는 것이 좋습니다. 이것은 INSERT IGNORE 사용하여 수행 할 수 있습니다.

다음 예제 데이터베이스를 고려하십시오.

SELECT * FROM `people`;
--- Produces:
+----+------+
| id | name |
+----+------+
|  1 | john |
|  2 | anna |
+----+------+


INSERT IGNORE INTO `people` (`id`, `name`) VALUES
    ('2', 'anna'), --- Without the IGNORE keyword, this record would produce an error
    ('3', 'mike');

SELECT * FROM `people`;
--- Produces:
+----+--------+
| id |  name  |
+----+--------+
|  1 |  john  |
|  2 |  anna  |
|  3 |  mike  |
+----+--------+

기억해야 할 중요한 점은 INSERT IGNORE 도 자동으로 다른 오류를 건너 뛸 것이고, 여기에 MySQL의 공식 문서가 말하고있는 것이 있습니다 :

IGNORE가 지정되지 않은 경우 오류를 트리거하는 데이터 변환은 명령문을 중단합니다. IGNORE를 사용하면 유효하지 않은 값이 가장 가까운 값으로 조정되고 삽입됩니다. 경고가 생성되지만 명령문은 중단되지 않습니다.

참고 : - 아래 섹션은 완전성을 위해 추가되었지만 모범 사례로 간주되지 않습니다 (예 : 테이블에 다른 열이 추가 된 경우).

테이블의 모든 열에 대해 해당 열의 값을 지정하면 다음과 같이 INSERT 문의 열 목록을 무시할 수 있습니다.

INSERT INTO `my_table` VALUES 
        ('data_1', 'data_2'),
        ('data_1', 'data_3'),
        ('data_4', 'data_5');

INSERT SELECT (다른 테이블에서 데이터 삽입)

이것은 SELECT 문을 사용하여 다른 테이블의 데이터를 삽입하는 기본 방법입니다.

INSERT INTO `tableA` (`field_one`, `field_two`) 
   SELECT `tableB`.`field_one`, `tableB`.`field_two` 
   FROM `tableB` 
   WHERE `tableB`.clmn <> 'someValue'
   ORDER BY `tableB`.`sorting_clmn`;

SELECT * FROM 일 수 있지만 tableAtableB 는 일치하는 열 개수와 해당 데이터 유형을 tableB 합니다 .

AUTO_INCREMENT 가있는 열은 VALUES 절이있는 INSERT 와 같이 처리됩니다.

이 구문을 사용하면 테이블을 다른 테이블의 데이터로 쉽게 채울 수 있으며, 삽입시 데이터를 필터링 할 때 더욱 그렇습니다.

AUTO_INCREMENT + LAST_INSERT_ID ()를 포함한 INSERT

테이블에 AUTO_INCREMENT PRIMARY KEY 가 있으면 일반적으로 테이블에 해당 열을 삽입하지 않습니다. 대신 다른 모든 열을 지정하고 새 ID가 무엇인지 물어보십시오.

CREATE TABLE t (
    id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL,
    this ...,
    that ...,
    PRIMARY KEY(id) );

INSERT INTO t (this, that) VALUES (..., ...);
SELECT LAST_INSERT_ID() INTO @id;
INSERT INTO another_table (..., t_id, ...) VALUES (..., @id, ...);

LAST_INSERT_ID() 는 세션에 연결되어 있으므로 여러 연결이 동일한 테이블에 삽입되는 경우에도 각각 고유 ID가 부여됩니다.

클라이언트 API는 아마도 얻기의 다른 방법이 LAST_INSERT_ID() 실제로 수행하지 않고 SELECT 하고 그것을 떠나는 대신 클라이언트로 값을 전달 @variable MySQL의 내부. 그러한 것이 일반적으로 바람직합니다.

더 길고 자세한 예

IODKU의 "정상적인"사용은 AUTO_INCREMENT PRIMARY KEY 아닌 UNIQUE 키를 기반으로 "duplicate key"를 트리거하는 것입니다. 다음은 그러한 것을 보여줍니다. INSERT에 id 를 제공하지 않습니다 .

수행 할 예제 설정 :

CREATE TABLE iodku (
    id INT AUTO_INCREMENT NOT NULL,
    name VARCHAR(99) NOT NULL,
    misc INT NOT NULL,
    PRIMARY KEY(id),
    UNIQUE(name)
) ENGINE=InnoDB;

INSERT INTO iodku (name, misc)
    VALUES
    ('Leslie', 123),
    ('Sally', 456);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0
+----+--------+------+
| id | name   | misc |
+----+--------+------+
|  1 | Leslie |  123 |
|  2 | Sally  |  456 |
+----+--------+------+

IODKU가 관련 id 검색하는 "업데이트"및 LAST_INSERT_ID() 를 수행하는 경우 :

INSERT INTO iodku (name, misc)
    VALUES
    ('Sally', 3333)            -- should update
    ON DUPLICATE KEY UPDATE    -- `name` will trigger "duplicate key"
    id = LAST_INSERT_ID(id),
    misc = VALUES(misc);
SELECT LAST_INSERT_ID();       -- picking up existing value
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                2 |
+------------------+

IODKU가 "삽입"을 수행하고 LAST_INSERT_ID() 가 새 id 검색하는 경우 :

INSERT INTO iodku (name, misc)
    VALUES
    ('Dana', 789)          -- Should insert
    ON DUPLICATE KEY UPDATE
    id = LAST_INSERT_ID(id),
    misc = VALUES(misc);
SELECT LAST_INSERT_ID();   -- picking up new value
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                3 |
+------------------+

결과 테이블 내용 :

SELECT * FROM iodku;
+----+--------+------+
| id | name   | misc |
+----+--------+------+
|  1 | Leslie |  123 |
|  2 | Sally  | 3333 |  -- IODKU changed this
|  3 | Dana   |  789 |  -- IODKU added this
+----+--------+------+

잃어버린 AUTO_INCREMENT ids

여러 '삽입'기능으로 ID를 구울 수 있습니다. 다음은 InnoDB를 사용하는 예제입니다 (다른 엔진은 다르게 작동 할 수 있음).

CREATE TABLE Burn (
    id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL,
    name VARCHAR(99) NOT NULL,
    PRIMARY KEY(id),
    UNIQUE(name)
        ) ENGINE=InnoDB;

INSERT IGNORE INTO Burn (name) VALUES ('first'), ('second');
SELECT LAST_INSERT_ID();          -- 1
SELECT * FROM Burn ORDER BY id;
  +----+--------+
  |  1 | first  |
  |  2 | second |
  +----+--------+

INSERT IGNORE INTO Burn (name) VALUES ('second');  -- dup 'IGNOREd', but id=3 is burned
SELECT LAST_INSERT_ID();          -- Still "1" -- can't trust in this situation
SELECT * FROM Burn ORDER BY id;
  +----+--------+
  |  1 | first  |
  |  2 | second |
  +----+--------+

INSERT IGNORE INTO Burn (name) VALUES ('third');
SELECT LAST_INSERT_ID();           -- now "4"
SELECT * FROM Burn ORDER BY id;    -- note that id=3 was skipped over
  +----+--------+
  |  1 | first  |
  |  2 | second |
  |  4 | third  |    -- notice that id=3 has been 'burned'
  +----+--------+

이것을 (대략) 이런 식으로 생각하십시오 : 먼저 삽입은 얼마나 많은 행 삽입 될지를 보입니다. 그런 다음 해당 테이블의 auto_increment에서 많은 값을 가져옵니다. 마지막으로 필요에 따라 ID를 사용하여 행을 삽입하고 남은 부분을 태우십시오.

남은 부분을 복구 할 수있는 유일한 시간은 시스템이 종료되었다가 다시 시작되는 경우입니다. 재시작시 효과적으로 MAX(id) 가 수행됩니다. 이것은 구워 졌거나 가장 높은 id의 DELETEs 에 의해 해방 된 ID를 재사용 할 수 있습니다.

기본적으로 INSERT ( DELETE + INSERT REPLACE 포함)의 모든 특성은 ID를 구울 수 있습니다. InnoDB에서, 글로벌 (세션이 아님!) 변수 인 innodb_autoinc_lock_mode 는 어떤 일이 일어나고 있는지를 제어하는데 사용될 수 있습니다.

긴 문자열을 AUTO INCREMENT id 로 "정규화"하면 쉽게 굽기 작업이 수행 될 수 있습니다. 이것은 당신이 선택한 INT 의 크기가 넘칠 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow