MySql:用于拆分、返回表的存储过程

MySql:用于拆分、返回表的存储过程,mysql,Mysql,我发现了很多MySql返回字符串第X部分的拆分过程示例。但我需要一个拆分过程来返回拆分字符串的所有部分,例如: SELECT split(",", "1,2,3,4,5,6"); 应该返回 +-------+ | split | +-------+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | +-------+ 我试过: DELIMITER $$ CREATE PROCEDURE `split`(delimeter

我发现了很多MySql返回字符串第X部分的拆分过程示例。但我需要一个拆分过程来返回拆分字符串的所有部分,例如:

SELECT split(",", "1,2,3,4,5,6");
应该返回

+-------+
| split |
+-------+
|     1 |
|     2 |
|     3 |
|     4 |
|     5 |
|     6 |
+-------+
我试过:

DELIMITER $$

CREATE PROCEDURE `split`(delimeter VARCHAR(1),txt VARCHAR(65535))
RETURNS split TABLE (
  part varchar(1024) NOT NULL)
DETERMINISTIC
BEGIN

DECLARE pos, posOld;

set pos := locate(delimeter,txt);
set posOld = 1;

WHILE pos > 0 DO
 set part := subst(text, posOld, pos-1);
 set posOld := pos+1;
 insert into split (`part`) values (part);

 set pos := locate(delimeter, txt, posOld);
END WHILE;

END$$
但是得到错误:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'split TABLE (part varchar(1024) NOT NULL)

正确的方法是什么?

您只能用普通SQL来实现这一点
这个技巧是使用MySQL数字生成器和嵌套的子字符串索引函数相结合

查询

SELECT
  DISTINCT 
    SUBSTRING_INDEX(SUBSTRING_INDEX(@CSV, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number  := @number + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN (
  SELECT @CSV := '1,2,3,4,5'
) AS init_user_param
此查询将生成从1到100的数字
因此,最终查询最多可以支持100个分隔的值

SELECT 
 (@number  := @number + 1) AS number
FROM (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_1
CROSS JOIN (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_2
CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
见演示

现在我们将使用

查询

SELECT
  DISTINCT 
    SUBSTRING_INDEX(SUBSTRING_INDEX(@CSV, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number  := @number + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN (
  SELECT @CSV := '1,2,3,4,5'
) AS init_user_param
将[position]替换为从逗号分隔字符串中提取的0-5之间的数字

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('1,2,3,4,5', ',', [position]), ',', -1) AS split;
见演示

现在我们了解了将这两个查询组合到一个工作解决方案中的基础知识

查询

SELECT
  DISTINCT 
    SUBSTRING_INDEX(SUBSTRING_INDEX(@CSV, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number  := @number + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN (
  SELECT @CSV := '1,2,3,4,5'
) AS init_user_param

请参见演示

您只能使用纯SQL来完成此操作
这个技巧是使用MySQL数字生成器和嵌套的子字符串索引函数相结合

查询

SELECT
  DISTINCT 
    SUBSTRING_INDEX(SUBSTRING_INDEX(@CSV, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number  := @number + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN (
  SELECT @CSV := '1,2,3,4,5'
) AS init_user_param
此查询将生成从1到100的数字
因此,最终查询最多可以支持100个分隔的值

SELECT 
 (@number  := @number + 1) AS number
FROM (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_1
CROSS JOIN (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_2
CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
见演示

现在我们将使用

查询

SELECT
  DISTINCT 
    SUBSTRING_INDEX(SUBSTRING_INDEX(@CSV, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number  := @number + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN (
  SELECT @CSV := '1,2,3,4,5'
) AS init_user_param
将[position]替换为从逗号分隔字符串中提取的0-5之间的数字

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('1,2,3,4,5', ',', [position]), ',', -1) AS split;
见演示

现在我们了解了将这两个查询组合到一个工作解决方案中的基础知识

查询

SELECT
  DISTINCT 
    SUBSTRING_INDEX(SUBSTRING_INDEX(@CSV, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number  := @number + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN (
  SELECT @CSV := '1,2,3,4,5'
) AS init_user_param

请参见演示

您正在混淆过程和函数-过程没有返回,mysql不支持表值函数。这永远不会像您希望的那样工作。。无法使用SELECT调用存储过程您需要使用CALL。。。可以使函数在select上工作,但不能返回多个记录。您将过程和函数混为一谈-过程没有返回,mysql不支持表值函数。这永远不会像您希望的那样工作。。无法使用SELECT调用存储过程您需要使用CALL。。。可以使函数在select上工作,但不能返回多条记录。