修改嵌套父程序代码以使用名称而不是 ID

Posted

技术标签:

【中文标题】修改嵌套父程序代码以使用名称而不是 ID【英文标题】:Modify nested parents procedure code to work with name instead of ID 【发布时间】:2019-02-08 21:07:24 【问题描述】:

我找到了一个我找了几个月的大宝,一个列出所有父类别到子类别的 SQL 过程,以便生成面包屑或提供类别搜索建议。但它需要类别 ID 才能找到它的父母,我想修改它以使用类别名称,因为我正在制作一个搜索框,提供搜索建议以显示类别及其所有父母。

来自this link的代码。

CREATE PROCEDURE `getAllParentCategories`( IN idCat int, IN intMaxDepth int)
BEGIN
DECLARE chrProcessed TEXT;
DECLARE quit INT DEFAULT 0;
DECLARE done INT DEFAULT 0;
DECLARE Level INT DEFAULT 0;
DECLARE idFetchedCategory INT;
DECLARE chrSameLevelParents TEXT;
DECLARE chrFullReturn TEXT;
DECLARE cur1 CURSOR FOR SELECT parent_id FROM sb_categories WHERE website_id IN (@param);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

SET chrFullReturn = '';
SET @param = idCat;
set chrProcessed = concat('|',idCat, '|');
myloop:LOOP
      IF quit = 1 THEN
        leave myloop;
      END IF;

      OPEN cur1;

      SET chrSameLevelParents = '';
      FETCH cur1 INTO idFetchedCategory;
      while(not done) do
          SET Level = Level + 1;
          IF idFetchedCategory > 0 THEN

                if NOT INSTR(chrProcessed,concat('|',idFetchedCategory, '|')) > 0 THEN
                      if CHAR_LENGTH(chrSameLevelParents) > 0 then
                        set chrSameLevelParents = concat( idFetchedCategory, ',', chrSameLevelParents );
                      else
                        set chrSameLevelParents = idFetchedCategory;
                      end if;

                      set chrProcessed = concat('|',idFetchedCategory, '|', chrProcessed );
                 end if;

           END IF;
           FETCH cur1 INTO idFetchedCategory;

      end while;
      CLOSE cur1;

      IF Level > intMaxDepth THEN SET done =1; SET quit = 1; END IF;

      if CHAR_LENGTH(chrSameLevelParents) > 0 THEN
        if CHAR_LENGTH(chrFullReturn) > 0 THEN
            set chrFullReturn = concat( chrFullReturn, ',', chrSameLevelParents );
        ELSE
            set chrFullReturn = chrSameLevelParents;
        END IF;

        SET @param = chrSameLevelParents;
        SET chrSameLevelParents = '';
        SET done = 0;

      ELSE
        SET quit = 1;
      END IF;
END LOOP;

SET @strQuery = concat('SELECT website_id, name FROM sb_categories WHERE website_id IN (',chrFullReturn,')'); PREPARE stmt1 FROM @strQuery;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END

我的表结构就这么简单:

+------------+-------------+-----------+
| website_id | name        | parent_id |
+------------+-------------+-----------+
| 1          | Electronics |         0 |
+------------+-------------+-----------+
| 2          | Computers   |         1 |
+------------+-------------+-----------+
| 3          | Asus        |         2 |
+------------+-------------+-----------+
| 4          | Food        |         0 |
+------------+-------------+-----------+
| 5          | Chicken     |         4 |
+------------+-------------+-----------+

我希望当用户搜索“华硕”时,我会得到一个显示“3-Asus,2-Computers,1-Electronics”的表格结果,以便在下拉菜单中显示,如“Electronics -> Computers -> Asus”。

现在,如果我使用:call getAllParentCategories(3, 10),它会按预期工作,我希望让它像 call getAllParentCategories('asus', 10) 一样工作,但我的 SQL 知识对我没有帮助。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

您想更改过程,使其接受类别名称而不是类别 ID 作为第一个参数。您的过程的输出应保持不变。

一种解决方案是在查询中添加一个额外的步骤,从nameCat 参数初始化idCat 变量:

CREATE PROCEDURE `getAllParentCategories`( IN nameCat VARCHAR(255), IN intMaxDepth int)
BEGIN
    ...
    SET chrFullReturn = '';
    SELECT @param := website_id FROM sb_categories WHERE name = nameCat;
    set chrProcessed = concat('|',@param, '|');
    ...

其余代码应保持不变。

请注意,只要类别名称是唯一的,这将正常工作......您可能需要在此列上创建一个唯一约束:

ALTER TABLE sb_categories ADD CONSTRAINT UC_name UNIQUE (name);

【讨论】:

感谢您的帮助。我刚刚将( IN nameCat int 更改为( IN nameCat VARCHAR(255) @tinyCoder:欢迎!我也修复了答案中的数据类型。 专线小巴,你好。您能否提供一个解决方案来避免该类别的唯一名称?我有很多相似的名字,但在不同的父类别下,我需要它们都出现,这可能吗?

以上是关于修改嵌套父程序代码以使用名称而不是 ID的主要内容,如果未能解决你的问题,请参考以下文章

如何将嵌套 div 向上移动两个 div 级别以匹配父级?

如何修改应用程序图标和应用程序名称以进行 MDM 分发 - 原生应用程序的品牌重塑

BQ数组查找:类似于NTH,但基于索引,而不是位置

易语言怎样实现让自己程序窗口嵌套到别的程序窗口中

前端开发规范CSS

获取不同域中的iframe父名称[重复]