Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Podziel ciąg i przeprowadź pętlę przez wartości w procedurze MySql

Musisz być trochę bardziej ostrożny przy manipulowaniu strunami. Nie możesz użyć REPLACE() w tym celu, ponieważ zastąpi to wiele wystąpień, uszkadzając dane, jeśli jeden element na liście rozdzielanej przecinkami jest podciągiem innego elementu. INSERT() funkcja ciągów jest to lepsze, nie mylić z INSERT instrukcja używana do wstawiania do tabeli.

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 ;

Następnie tabela do testowania:

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

Nowa tabela jest pusta.

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

Wywołaj procedurę.

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

Zauważ, że „1 wiersz dotyczy” nie oznacza tego, czego byś się spodziewał. Odnosi się do ostatniej wstawki, którą zrobiliśmy. Ponieważ wstawiamy jeden wiersz na raz, jeśli procedura wstawia co najmniej jeden wiersz, zawsze otrzymasz 1; jeśli procedura nic nie wstawi, dostaniesz 0 wierszy.

Czy to zadziałało?

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. Wiele tabel LINQ to SQL pozostawiło sprzężenie zewnętrzne

  2. Jak zainstalować MySQL na Ubuntu?

  3. Błąd mysql node.js:ECONNREFUSED

  4. pip install mysqlclient zwraca błąd krytyczny C1083:Nie można otworzyć pliku:'mysql.h':Brak takiego pliku lub katalogu

  5. Wskazówki dotyczące monitorowania MySQL dla Moodle