1. 程式人生 > 其它 >Mysql 根據父節點查詢所有子節點函式

Mysql 根據父節點查詢所有子節點函式

技術標籤:MySQLRevit二次開發

資料量5k+,參照部落格中給出的函式,執行一次需要15s,耗時太長,所以最終沒有選擇在Mysql中進行資料的遍歷,而是採用在使用者選取父節點時,在類中遍歷,總體耗時會小很多,也不會給使用者帶來尺鈍感。

平時使用Mysql 的函式不多,所以還是記錄下來以後學習使用

  1. 在Mysql 中函式建立後會提示This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de的錯誤資訊,參照部落格:MySQL 建立函式報錯 This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you might
    want to use the less safe log_bin_trust_function_creators

    解決辦法由兩個:
    • 在函式體前寫一句 set global log_bin_trust_function_creators=TRUE; 但是每次重啟後都需要重新執行一遍
    • 在my.cnf配置檔案中設定
      log-bin-trust-function-creators=1 重啟後即可生效
  2. 如果函式建立後修改執行會提示:MySQL: create a function but it already exists
    需要在函式提前新增DROP FUNCTION IF EXISTS funcName;

    解決答案:stackflow
  3. 函式體,這裡我也是似懂非懂,直接貼地址:Mysql遞迴獲取某個父節點下面的所有子節點和子節點上的所有父節點
    其中IF(exp1,exp2,exp3)將會依次執行三個表示式,如果1不成功就執行2,同樣不成功執行3
    FIND_IN_SET :是查詢在改字串中是否有指定的字元,
    在這裡插入圖片描述
create table mrm_level(
    id int auto_increment,
    name char(255) not null ,
    parentId int not null,
    contentId int not null ,
    path longtext ,
    type boolean,
    primary key (id)
)engine = InnoDB default charset = utf8;




drop function if exists getChildList;
delimiter  $$
create function getChildList(pid int) returns varchar(2000)
begin
    declare str varchar(100);
    declare cid varchar(100);
    set str = ' ';
    set cid = pid;
    while cid is not null do
        set str = concat(str,',',cid);
        select group_concat(contentId) into cid from mrm_level where find_in_set(parentId,cid)>0 ;
        end while;
    set str = substring(str,2);
    return str;
end$$;
    delimiter ;

select * from mrm_level where find_in_set(id,getChildList(2)) and type =0