1. 程式人生 > >用mysql儲存過程代替遞迴查詢 用mysql儲存過程代替遞迴查詢

用mysql儲存過程代替遞迴查詢 用mysql儲存過程代替遞迴查詢

用mysql儲存過程代替遞迴查詢

查詢此表某個id=4028ab535e370cd7015e37835f52014b(公司1)下的所有資料

正常情況下,我們採用遞迴演算法查詢,如下

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public  void  findCorpcompanyListByParentId(List<UapcompanyVo> vos,String parentId){          UapcompanyParam param =  new  UapcompanyParam();
         param.setParentid(parentId);          List<Uapcompany> companyList = uapcompanyDao.finduapcompanyList(param);         
UapcompanyVo uapcompanyVo =  null ;          for (Uapcompany uapcompany : companyList){              uapcompanyVo =  new  UapcompanyVo();              uapcompanyVo =  new  UapcompanyVo();              uapcompanyVo.setId(uapcompany.getId());              uapcompanyVo.setName(uapcompany.getName());              uapcompanyVo.setParentid(uapcompany.getParentid());              vos.add(uapcompanyVo);              this .findCorpcompanyListByParentId(vos, uapcompany.getParentid());          } }

遞迴查詢也能實現該需求,但是這樣有兩個缺點:一,效能很差 ,因為每遞迴一次至少呼叫一次資料鏈接;二,如果資料量很大的話,可能會導致溢位,當然可以修改虛擬機器引數,不過這也是治標不治本的方法

接下來,我們看一下儲存過程實現查詢:

選擇函式-->右鍵-->選擇新建函式

選擇過程

新增入參引數,如下圖所示

完成,如下圖所示

在begin end區域編寫儲存過程內容

 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 BEGIN      #宣告一個flag變數,預設值為-99      DECLARE  flag  INT  DEFAULT  -99;            #建立companyTempTabl_Qurey臨時表      CREATE  TEMPORARY  TABLE  IF  NOT  EXISTS companyTempTabl_Qurey (          id  VARCHAR (32)  NOT  NULL ,          ` name VARCHAR (100),          attr  VARCHAR (30),          parentId  VARCHAR (32)      );      TRUNCATE  TABLE  companyTempTabl_Qurey;        #建立companyTempTabl_Result臨時表         CREATE  TEMPORARY  TABLE  IF  NOT  EXISTS companyTempTabl_Result (          id  VARCHAR  (32)  NOT  NULL ,          ` name VARCHAR  (100),          attr  VARCHAR  (30),          parentId  VARCHAR  (32)      );      TRUNCATE  TABLE  companyTempTabl_Result;            #根據引數 parentId 查詢資料,並插入companyTempTabl_Qurey臨時表      INSERT  INTO  companyTempTabl_Qurey (          id,          ` name `,          attr,          parentId      SELECT      uapcompany.id,      uapcompany.` name `,      uapcompany.attr,      uapcompany.parentId      FROM  uapcompany      WHERE  uapcompany.parentId = `parentId`;              #根據引數 parentId 查詢資料,並插入companyTempTabl_Result臨時表      INSERT  INTO  companyTempTabl_Result (          id,          ` name `,          attr,          parentId      SELECT      uapcompany.id,      uapcompany.` name `,      uapcompany.attr,      uapcompany.parentId      FROM  uapcompany      WHERE  uapcompany.parentId = `parentId`;            #根據引數 parentId 統計查詢總數,並賦值給變數flag      SELECT  count (1)  INTO  flag      FROM  uapcompany      WHERE  uapcompany.parentId = `parentId`;            #如果flag 大於 0,則進行迴圈      WHILE flag > 0 DO          #建立companyTempTabl_temp 臨時表          CREATE  TEMPORARY  TABLE  IF  NOT  EXISTS companyTempTabl_temp (              id  VARCHAR  (32)  NOT  NULL ,              ` name VARCHAR  (100),              attr  VARCHAR  (30),              parentId  VARCHAR  (32)          );          TRUNCATE  TABLE  companyTempTabl_temp;                    #資料庫表uapcompany關聯臨時表companyTempTabl_Qurey查詢,並將查詢結果插入 臨時表companyTempTabl_temp          INSERT  INTO  companyTempTabl_temp (id, ` name `, attr, parentId)  SELECT              uapcompany.id,              uapcompany.` name `,              uapcompany.attr,              uapcompany.parentId          FROM              uapcompany,              companyTempTabl_Qurey          WHERE              uapcompany.parentId = companyTempTabl_Qurey.id;                    #刪除臨時表companyTempTabl_Qurey資料          DELETE  FROM  companyTempTabl_Qurey;                    #將臨時表companyTempTabl_temp的資料 插入companyTempTabl_Qurey臨時表,用作下一個迴圈的條件          INSERT  INTO  companyTempTabl_Qurey (id, ` name `, attr, parentId)  SELECT              companyTempTabl_temp.id,              companyTempTabl_temp.` name `,              companyTempTabl_temp.attr,              companyTempTabl_temp.parentId          FROM              companyTempTabl_temp;                    #將臨時表companyTempTabl_temp的資料 插入到companyTempTabl_Result臨時表(該表的資料也是我們最終要返回的資料)          INSERT  INTO  companyTempTabl_Result (id, ` name `, attr, parentId)  SELECT              companyTempTabl_temp.id,              companyTempTabl_temp.` name `,              companyTempTabl_temp.attr,              companyTempTabl_temp.parentId          FROM              companyTempTabl_temp;                    #刪除companyTempTabl_temp資料          DROP  TABLE  companyTempTabl_temp;                    #資料庫表uapcompany關聯 臨時表companyTempTabl_Qurey查詢統計,並將結果賦值給變數flag          SELECT              count (1)  INTO  flag          FROM              uapcompany,              companyTempTabl_Qurey          WHERE              uapcompany.parentId = companyTempTabl_Qurey.id;      END  WHILE;      SELECT  id ,` name `,attr,parentId   FROM  companyTempTabl_Result;   END

 然後儲存

測試一下,點選執行

輸入引數,點選確定,結果如下圖所示

我們在dao層只需要呼叫一次該 儲存過程,就可以返回自己想要的資料,儲存過程中建立的臨時表隨著連結的釋放自動刪除

 

查詢此表某個id=4028ab535e370cd7015e37835f52014b(公司1)下的所有資料

正常情況下,我們採用遞迴演算法查詢,如下

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public  void  findCorpcompanyListByParentId(List<UapcompanyVo> vos,String parentId){          UapcompanyParam param =  new  UapcompanyParam();          param.setParentid(parentId);          List<Uapcompany> companyList = uapcompanyDao.finduapcompanyList(param);          UapcompanyVo uapcompanyVo =  null ;          for (Uapcompany uapcompany : companyList){              uapcompanyVo =  new  UapcompanyVo();              uapcompanyVo =  new  UapcompanyVo();              uapcompanyVo.setId(uapcompany.getId());              uapcompanyVo.setName(uapcompany.getName());              uapcompanyVo.setParentid(uapcompany.getParentid());              vos.add(uapcompanyVo);              this .findCorpcompanyListByParentId(vos, uapcompany.getParentid());          } }

遞迴查詢也能實現該需求,但是這樣有兩個缺點:一,效能很差 ,因為每遞迴一次至少呼叫一次資料鏈接;二,如果資料量很大的話,可能會導致溢位,當然可以修改虛擬機器引數,不過這也是治標不治本的方法

接下來,我們看一下儲存過程實現查詢:

選擇函式-->右鍵-->選擇新建函式

選擇過程

新增入參引數,如下圖所示

完成,如下圖所示

在begin end區域編寫儲存過程內容

 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 BEGIN      #宣告一個flag變數,預設值為-99      DECLARE  flag  INT  DEFAULT  -99;            #建立companyTempTabl_Qurey臨時表      CREATE  TEMPORARY  TABLE  IF  NOT  EXISTS companyTempTabl_Qurey (          id  VARCHAR (32)  NOT  NULL ,          ` name VARCHAR (100),          attr  VARCHAR (30),          parentId  VARCHAR (32)      );      TRUNCATE  TABLE  companyTempTabl_Qurey;        #建立companyTempTabl_Result臨時表

相關推薦

mysql儲存過程代替查詢 mysql儲存過程代替查詢

用mysql儲存過程代替遞迴查詢 查詢此表某個id=4028ab535e370cd7015e37835f52014b(公司1)下的所有資料 正常情況下,我們採用遞迴演算法查詢,如下 1

mysql查詢mysql中從子類ID查詢所有父類(做無限分類經常到)

由於mysql 不支援類似 oracle with ...connect的 遞迴查詢語法之前一直以為類似的查詢要麼用儲存過程要麼只能用程式寫遞迴查詢.現在發現原來一條sql語句也是可以搞定的先來看資料表的結構如下:id  name    parent_id&n

MySql、Oracle(通用方法)查詢生成檔案目錄樹(JAVA實現 過程中不訪問資料庫,之前只訪問兩次 進行前資料準備)

查詢檔案樹 實體類 public class TradeInfoFile { ​ // 檔案編碼(子) private String fileCode; // 所屬檔案編碼(父) private String belongFileCode; // 交易

Oracle sql,mybatis的查詢,與儲存過程呼叫

Oralce 遞迴sql    一、查詢所有子節點 SELECT * FROM district ST

Python函式之實現二分查詢

遞迴:簡單來說就是引用(或者呼叫)自身的意思。 #階乘 def factorical(n): result=n for i in range(1,n): result *=i return result print(factorical(12)) 輸出

golang mysql多語句查詢及呼叫儲存過程

之前的golang版本,由於sql標準庫不支援多結果集的返回,所以也就影響了儲存過程,那時候只能呼叫插入和更新類的儲存過程,即db.exec(“call function_name”), 從golang

Sqlwith 實現查詢

1.遞迴原理(摘自網上)    遞迴CTE最少包含兩個查詢(也被稱為成員)。第一個查詢為定點成員,定點成員只是一個返回有效表的查詢,用於遞迴的基礎或定位點。第二個查詢被稱為遞迴成員,使該查詢稱為遞迴成

mysql儲存過程---返回列表資料需要到遊標

說明:在呼叫儲存過程後,未遇到錯誤訊息時處理程式未被啟用,當執行INSERT語句出現出錯訊息時,MySQL檢查是否為這個錯誤程式碼定義了處理程式。如果有,則啟用該處理程式,本例中,INSERT語句導致的錯誤訊息剛好是SQLSTATE程式碼中的一條。接下來執行處理程式的附加語句(SET @x2=1)。此後,My

mysql刪庫跑路小指令碼——儲存過程刪除全部表(不刪除資料庫)

建立儲存過程指令碼DELIMITER $$ CREATE PROCEDURE `drop_all_tables`() BEGIN DECLARE count INT; DECLARE tb VARCHAR(200); DECLARE dbname VA

mysql存儲過程及(java調

mysql 存儲過程create procedure DeleteDataByPdfDocId ( IN pdfDocId varchar(100) ) BEGIN #根據pdfDocId刪除數據 DELETE FROM pdf_formula WHERE PDF_DOCID = pdfDocId ;

存儲過程歸調(樹形結構路徑的快速生成)

fault recursion 結束 快速 substr 手動 默認值 這不 字符 最近在做表數據整理的時候碰到這樣的一個問題,我有一張permission表,其數據結構為樹形結構,裏面有個permission_path字段用於記錄根節點到父節點的路徑(以pe

MySQL之存儲過程創建和調

可讀性 primary 數據表 刪掉 start dml lec 插入 ora 一、MySQL存儲過程_創建-調用 1.1存儲過程:SQL中的“腳本”1.創建存儲過程2.調用存儲過程3.存儲過程體4.語句標簽塊     二、MySQL存儲過程簡單介紹: 存儲過程(Store

MySQL存儲過程創建及調方法

all 關鍵詞 () 修改 如何 我們 cal mys 調用方法 MySQL存儲過程是一個sql語句,那麽我們如何創建呢,MySQL存儲過程創建及修改,刪除操作。 1,存儲過程創建 DELIMITER //CREATE PROCEDURE Ge

mysql高階包含索引建立優化_函式_儲存過程_觸發器_及遊標

Mysql 高階部分   (1)索引(index)1 (2)檢視(view)2 (3)觸發器(trigger)6 (4)遊標(cursor)8 (5)事務(Transaction)10 (6)儲存過程(Stored Procedure)1

springboot中多個不同物件的屬性進行比較,將不同的值使用陣列查詢出,並儲存在意向表中

多表維護 @MethodParameter(desc="orgTenantTypeQueryAll",input="user",postType={},postName="",queryString="",httpMethod="get",userParam="user

python寫:完成一個員工管理系統 要求儲存員工的工號、姓名、年齡、性別、工資 1、員工錄入 2、查詢員工資訊 3、修改員工資訊 4、刪除 5、根據工號檢視 6、退出

   完成一個員工管理系統    要求儲存員工的工號、姓名、年齡、性別、工資    1、員工錄入    2、查詢員工資訊    3、修改員工資訊    4、刪除  &nb

MySQL儲存過程中的3種迴圈,儲存過程的基本語法,ORACLE與MYSQL儲存過程/函式的使用區別,退出儲存過程方法

  學無止境 部落格園   首頁   新隨筆   聯絡   訂閱  管理 隨筆-1968  評論-103  文章-4&

mysql小白之旅——進階篇2——儲存過程、事件、觸發器、事務、分散式事務

14.儲存過程的寫法 1)定義條件和處理 --CONDITION --HANDLER 2)游標 CURSOR --DECLARE --OPEN --FETCH --CLOSE 3)流程控制 --IF語句 --CASE語句 --LOOP語句 --LEAVE語句  相當於br

mysql學習筆記(二)--查詢語句的執行過程

最近在學習mysql實戰45講,覺得裡面的內容很受用,做一些筆記記錄下: 首先是mysql的一個基礎架構的解釋,如下圖:                從上圖我們可以清晰的看到,mysql的基礎架構主要分為兩個部分,一個是server層(負責大多數核心服務功能的實現),一個是儲存引擎層(負責資料的儲存與

Mysql資料庫如何檢視資料表table被哪些儲存過程procedure使用過

一、摘要 由於程式碼重構,修改了多張表結構,java後臺程式碼做相應修改處理,開發人員內測沒問題提交業務部門測試時發現,新客戶取不到產品價格,原因是儲存過程呼叫的還是就的資料表。為此,需要先找出哪些儲存過程使用到了這些表,然後修改。那麼問題來了,mysql資料庫