일부 사용 시나리오에서는 DML 작업 후 방금 작업된 데이터 행을 반환해야 합니다. 일반적으로 이를 구현하는 방법은 두 가지가 있습니다.
전자는 주로 SELECT 명령의 오버헤드를 증가시키는 반면 후자는 SQL 구현이 더 복잡하고 유연성은 떨어지도록 만듭니다(트리거 생성 필요).
따라서 RETURNING 구문의 설계는 주로 이 시나리오의 최적화를 목표로 하며, DML 명령 뒤에 RETURNING 키워드를 추가함으로써 상기 요구 사항을 유연하고 효율적으로 구현할 수 있습니다.
커널 버전 MySQL 5.7 20210330 이상
현재 MySQL 5.7 20210330 이상의 커널 버전은 INSERT ... RETURNING, REPLACE ... RETURNING, DELETE ... RETURNING을 지원합니다. 이 구문을 사용하면 INSERT/REPLACE/DELETE 명령(단위 statment)으로 작업된 모든 행을 반환할 수 있습니다. 또한, RETURNING은 prepared statements과 저장 과정 중의 사용도 지원합니다.
이 기능을 사용할 때 다음 사항에 주의해야 합니다.
MySQL [test]> CREATE TABLE `t1` (id1 INT);
Query OK, 0 rows affected (0.04 sec)
MySQL [test]> CREATE TABLE `t2` (id2 INT);
Query OK, 0 rows affected (0.03 sec)
MySQL [test]> INSERT INTO t2 (id2) values (1);
Query OK, 1 row affected (0.00 sec)
MySQL [test]> INSERT INTO t1 (id1) values (1) returning *, id1 * 2, id1 + 1, id1 * id1 as alias, (select * from t2);
+------+---------+---------+-------+--------------------+
| id1 | id1 * 2 | id1 + 1 | alias | (select * from t2) |
+------+---------+---------+-------+--------------------+
| 1 | 2 | 2 | 1 | 1 |
+------+---------+---------+-------+--------------------+
1 row in set (0.01 sec)
MySQL [test]> INSERT INTO t1 (id1) SELECT id2 from t2 returning id1;
+------+
| id1 |
+------+
| 1 |
+------+
1 row in set (0.01 sec)
MySQL [test]> CREATE TABLE t1(id1 INT PRIMARY KEY, val1 VARCHAR(1));
Query OK, 0 rows affected (0.04 sec)
MySQL [test]> CREATE TABLE t2(id2 INT PRIMARY KEY, val2 VARCHAR(1));
Query OK, 0 rows affected (0.03 sec)
MySQL [test]> INSERT INTO t2 VALUES (1,'a'),(2,'b'),(3,'c');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
MySQL [test]> REPLACE INTO t1 (id1, val1) VALUES (1, 'a');
Query OK, 1 row affected (0.00 sec)
MySQL [test]> REPLACE INTO t1 (id1, val1) VALUES (1, 'b') RETURNING *;
+-----+------+
| id1 | val1 |
+-----+------+
| 1 | b |
+-----+------+
1 row in set (0.01 sec)
MySQL [test]> CREATE TABLE t1 (a int, b varchar(32));
Query OK, 0 rows affected (0.04 sec)
MySQL [test]> INSERT INTO t1 VALUES
-> (7,'ggggggg'), (1,'a'), (3,'ccc'),
-> (4,'dddd'), (1,'A'), (2,'BB'), (4,'DDDD'),
-> (5,'EEEEE'), (7,'GGGGGGG'), (2,'bb');
Query OK, 10 rows affected (0.03 sec)
Records: 10 Duplicates: 0 Warnings: 0
MySQL [test]> DELETE FROM t1 WHERE a=2 RETURNING *;
+------+------+
| a | b |
+------+------+
| 2 | BB |
| 2 | bb |
+------+------+
2 rows in set (0.01 sec)
MySQL [test]> DELETE FROM t1 RETURNING *;
+------+---------+
| a | b |
+------+---------+
| 7 | ggggggg |
| 1 | a |
| 3 | ccc |
| 4 | dddd |
| 1 | A |
| 4 | DDDD |
| 5 | EEEEE |
| 7 | GGGGGGG |
+------+---------+
8 rows in set (0.01 sec)
MySQL [test]> CREATE TABLE `t` (id INT);
Query OK, 0 rows affected (0.03 sec)
MySQL [test]> delimiter $$
MySQL [test]> CREATE PROCEDURE test(in param INT)
-> BEGIN
-> INSERT INTO t (id) values (param) returning *;
-> END$$
Query OK, 0 rows affected (0.00 sec)
MySQL [test]> delimiter ;
MySQL [test]> CALL test(100);
+------+
| id |
+------+
| 100 |
+------+
1 row in set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
문제 해결에 도움이 되었나요?