mysql 用户定义的函数如何知道找到了选定的行?

how does mysql user defined function know a selected row was found?

a MYSQL 用户定义函数从 table 中选择一行。 UDF 代码如何确定所选行是否在 table?

中找到
CREATE FUNCTION snippetFolder_folderPath(folder_id int)
  RETURNS varchar(512)
  BEGIN

  declare    vFolder_id int;
  declare    vParent_id int;
  declare    vPath varchar(512) default '';
  declare    vFolderName varchar(256) default '';

  set        vFolder_id = folder_id;
  build_path:
  while (vFolder_id > 0) do


/* -------- how to know this select statement returns a row??  ---------- */
  select     a.parent_id, a.folderName
  into       vParent_id, vFolderName
  from       SnippetFolder a
  where      a.folder_id = vFolder_id;

  if         vPath = ' ' then
  set        vPath = vFolderName;
else
  set        vPath = concat_ws( '/', vFolderName, vPath );
  end if ;

  set        vFolder_id = vParent_id;
  end while ;

  return vPath;

  END

https://dev.mysql.com/doc/refman/8.0/en/select-into.html 说:

If the query returns no rows, a warning with error code 1329 occurs (No data), and the variable values remain unchanged.

因此您可以 declare a continue handler on warnings,类似于文档中的示例:

BEGIN
  DECLARE i INT DEFAULT 3;
  DECLARE done INT DEFAULT FALSE;
  retry:
    REPEAT
      BEGIN
        DECLARE CONTINUE HANDLER FOR SQLWARNING
          BEGIN
            SET done = TRUE;
          END;
        IF done OR i < 0 THEN
          LEAVE retry;
        END IF;
        SET i = i - 1;
      END;
    UNTIL FALSE END REPEAT;
END

我将留给您阅读文档并根据您的 table 和您的循环调整该示例。

或者,如果您使用的是 MySQL 8.0,则可以使用递归通用 table 表达式:

CREATE FUNCTION snippetFolder_folderPath(vFolder_id int)
  RETURNS varchar(512)
BEGIN

  DECLARE    vPath varchar(512) DEFAULT '';

  WITH RECURSIVE cte AS (
    SELECT folderName, parent_id, 0 AS height 
    FROM SnippetFolder WHERE folder_id = vFolder_id
    UNION
    SELECT f.folderName, f.parent_id, cte.height+1
    FROM SnippetFolder AS f JOIN cte ON cte.parent_id = f.folder_id 
  )
  SELECT GROUP_CONCAT(folderName ORDER BY height DESC SEPARATOR '/')
  INTO vPath
  FROM cte;

  RETURN vPath;
END

递归CTE结果是匹配vFolder_id行的所有祖先,然后可以使用GROUP_CONCAT()将它们连接在一起作为一个字符串。