Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Tách một chuỗi và lặp qua các giá trị trong Thủ tục MySql

Bạn sẽ cần phải cẩn thận hơn một chút với thao tác trên chuỗi của mình. Bạn không thể sử dụng REPLACE() cho điều này, vì điều đó sẽ thay thế nhiều lần xuất hiện, làm hỏng dữ liệu của bạn nếu một phần tử trong danh sách được phân tách bằng dấu phẩy là một chuỗi con của phần tử khác. INSERT() hàm chuỗi tốt hơn cho điều này, không bị nhầm lẫn với INSERT câu lệnh được sử dụng để chèn vào bảng.

DELIMITER $$

DROP PROCEDURE IF EXISTS `insert_csv` $$
CREATE PROCEDURE `insert_csv`(_list MEDIUMTEXT)
BEGIN

DECLARE _next TEXT DEFAULT NULL;
DECLARE _nextlen INT DEFAULT NULL;
DECLARE _value TEXT DEFAULT NULL;

iterator:
LOOP
  -- exit the loop if the list seems empty or was null;
  -- this extra caution is necessary to avoid an endless loop in the proc.
  IF CHAR_LENGTH(TRIM(_list)) = 0 OR _list IS NULL THEN
    LEAVE iterator;
  END IF;
 
  -- capture the next value from the list
  SET _next = SUBSTRING_INDEX(_list,',',1);

  -- save the length of the captured value; we will need to remove this
  -- many characters + 1 from the beginning of the string 
  -- before the next iteration
  SET _nextlen = CHAR_LENGTH(_next);

  -- trim the value of leading and trailing spaces, in case of sloppy CSV strings
  SET _value = TRIM(_next);

  -- insert the extracted value into the target table
  INSERT INTO t1 (c1) VALUES (_value);

  -- rewrite the original string using the `INSERT()` string function,
  -- args are original string, start position, how many characters to remove, 
  -- and what to "insert" in their place (in this case, we "insert"
  -- an empty string, which removes _nextlen + 1 characters)
  SET _list = INSERT(_list,1,_nextlen + 1,'');
END LOOP;

END $$

DELIMITER ;

Tiếp theo, một bảng để thử nghiệm:

CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `c1` varchar(64) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Bảng mới trống.

mysql> SELECT * FROM t1;
Empty set (0.00 sec)

Gọi thủ tục.

mysql> CALL insert_csv('foo,bar,buzz,fizz');
Query OK, 1 row affected (0.00 sec)

Lưu ý rằng "1 hàng bị ảnh hưởng" không có nghĩa là những gì bạn mong đợi. Nó đề cập đến lần chèn cuối cùng chúng tôi đã làm. Vì chúng tôi chèn từng hàng một, nếu thủ tục chèn ít nhất một hàng, bạn sẽ luôn nhận được số hàng là 1; nếu thủ tục không chèn gì, bạn sẽ nhận được 0 hàng bị ảnh hưởng.

Nó có hoạt động không?

mysql> SELECT * FROM t1;
+----+------+
| id | c1   |
+----+------+
|  1 | foo  |
|  2 | bar  |
|  3 | buzz |
|  4 | fizz |
+----+------+
4 rows in set (0.00 sec)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách cài đặt MySQL trên CentOS 6

  2. Cách sao chép bảng trong MySQL

  3. int (11) so với int (bất kỳ thứ gì khác)

  4. Di chuyển trực tuyến từ MySQL 5.6 Non-GTID sang MySQL 5.7 với GTID

  5. Đặt NOW () làm Giá trị Mặc định cho kiểu dữ liệu datetime?