sql >> Databáze >  >> RDS >> Mysql

Rozdělte řetězec a procházejte hodnoty v Proceduře MySql

Budete muset být trochu opatrnější s manipulací se strunou. Nemůžete použít REPLACE() protože to nahradí více výskytů a poškodí vaše data, pokud je jeden prvek v seznamu odděleném čárkami podřetězcem jiného prvku. INSERT() funkce řetězce je pro to lepší, nezaměňovat s INSERT příkaz používaný pro vkládání do tabulky.

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 ;

Dále tabulka pro testování:

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

Nová tabulka je prázdná.

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

Zavolejte proceduru.

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

Všimněte si, že "1 řádek ovlivněn" neznamená to, co byste očekávali. Odkazuje na poslední vložku, kterou jsme udělali. Protože vkládáme po jednom řádku, pokud procedura vloží alespoň jeden řádek, vždy získáte počet řádků 1; pokud procedura nic nevloží, bude ovlivněno 0 řádků.

Fungovalo to?

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



  1. Jak nainstalovat Nextcloud 15 na Ubuntu 18.04

  2. jak používat xmltable v oracle?

  3. Úvod do Hadoopu a velkých dat

  4. Vytvořte vztah v SQL