1. 程式人生 > >報表統計-mysql儲存過程

報表統計-mysql儲存過程

首先mysql如何建立一個儲存過程:

1.建立一個日常考核的儲存過程:

drop procedure if exists pr_dailycheck;

首先判斷是否存在同名的儲存過程,如果存在同名的儲存過程,可以將同名的儲存過程刪除

2.建立儲存過程

create PROCEDURE pr_dailycheck() 
begin 
select * from audit_queue_history; -- 這是一個sql語句
end; 

3.上面是比較簡單的儲存過程,下面我們繼續將這個儲存過程變的更加的複雜,複雜

   如何複雜,傳遞一個變數,我們的目的是查詢每天取號的數量,所以說我們要傳遞一個日期

create PROCEDURE pr_dailycheck(in daily1 VARCHAR(32)) 
begin 
declare daily varchar(32);
SET daily=daily1;
select * from audit_queue_history where DATE_FORMAT(GETNOTIME,'%Y-%m-%d')=DATE_FORMAT(daily,'%Y-%m-%d');
end; 

呼叫儲存過程:

CALL pr_dailycheck('2018-07-16');

上面是我們向儲存過程中傳遞一個引數,如何定義帶有引數的儲存過程,需要注意的是使用的關鍵字 是  in

4.上面是一個還算是比較簡單的儲存過程,我們可以在儲存過程中作很多的操作,下面我們在儲存過程中建立一個表,因為我們報表統計需要輸出不同的很多的欄位,並且每個欄位的每個欄位的查詢都會使用到不同的資料表,我們可以如果使用left join那樣可能太過麻煩,我們可以建立一個數據表,將查詢的結果存放在這個臨時的表裡面,最後遍歷這個臨時的表,不就是我們想要的結果了

所以下面我們開始在儲存過程裡面建立資料表:

create PROCEDURE pr_dailycheck(in daily1 VARCHAR(32)) 
begin 
declare daily varchar(32);
SET daily=daily1;
CREATE TEMPORARY TABLE IF NOT EXISTS tmpTable 
	(
		rowguid VARCHAR(50) PRIMARY KEY,-- 主鍵
    ouname VARCHAR(50),-- 部門名稱
		queuenum INT,-- 取號數
		consultnum INT(50), -- 諮詢答覆數量
		linkbnnum INT-- 關聯辦件的數量
	);
	TRUNCATE TABLE tmpTable; 
  select * from tmpTable;
end; 

這個時候我們如果繼續呼叫這樣的呼叫這個儲存過程,搜尋的結果如下:

其實這個就是我們在儲存過程裡面建立的一個臨時的表,但是這個表裡面還沒有資料,我們一個比較完整的儲存過程裡面應該應該存放資料,那麼如何來存放資料,下面我們關心的問題便是向這個臨時的表裡面插入資料

5.臨時表插入資料

當然我們向臨時表裡面插入資料也不是隨便把資料插入的,我們需要在庫裡面查詢到資料,然後插入到這個表裡面

比如上面的ouname

其實在這個之前,我們有必要了解一下有遊標,因為在插入資料到資料表中,我們常常會使用有遊標,而且遊標在儲存過程中應用也是十分的廣泛的,現在我們就來看一下如何來使用建立一個遊標

drop procedure if exists pr_dailycheck;
create PROCEDURE pr_dailycheck(in daily1 VARCHAR(32)) 
begin 
declare daily varchar(32);
DECLARE done INT DEFAULT FALSE;
declare ou_guid varchar(32);
declare ou_name varchar(32); 
DECLARE myCursor CURSOR FOR(select ouname from frame_ou);-- 建立遊標並且賦值為結果集合
DECLARE CONTINUE HANDLER for not found SET done = 1;
SET daily=daily1;
CREATE TEMPORARY TABLE IF NOT EXISTS tmpTable 
	(
		rowguid VARCHAR(50) PRIMARY KEY,-- 主鍵
    ouname VARCHAR(50),
		queuenum INT,
		consultnum INT(50), 
		linkbnnum INT
	);
	TRUNCATE TABLE tmpTable; 
  OPEN myCursor; -- 開啟遊標  
		myLoop: LOOP -- 開始迴圈體,myLoop為自定義迴圈名
		 FETCH myCursor into ou_name; -- 將遊標當前讀取行的資料,順序賦予自定義變數  
			 IF done=1 THEN -- 判斷是否繼續迴圈  
			 LEAVE myLoop; -- 結束迴圈  
			 END IF;
     INSERT INTO tmpTable(rowguid,ouname) values(UUID(),ou_name);
     END LOOP myLoop; -- 結束自定義迴圈體 
  CLOSE myCursor; -- 關閉遊標  
  select * from tmpTable;
end; 

上面其實是建立遊標,並且給遊標賦值一個結果的集合,當這些任務完成之後,這樣當然是不行的我們的報表統計需要的那是相當的複雜,,我們在迴圈裡面需要利用遍歷的變數在不同的表字段裡面進行查詢資料,然後賦值給一個變數最後將這個這些變數作為值插入到臨時表裡面,我們在迴圈的時候,可以同時在遊標裡面設計兩個變數:

drop procedure if exists pr_dailycheck;
create PROCEDURE pr_dailycheck(in daily1 VARCHAR(32)) 
begin 
declare daily varchar(32);
DECLARE done INT DEFAULT FALSE;
declare ou_guid varchar(50);
declare ou_name varchar(32); 
DECLARE myCursor CURSOR FOR(select ouname,ouguid from frame_ou where oucode like '%320700%');-- 建立遊標並且賦值為結果集合
DECLARE CONTINUE HANDLER for not found SET done = 1;
SET daily=daily1;
CREATE TEMPORARY TABLE IF NOT EXISTS tmpTable 
	(
		rowguid VARCHAR(50) PRIMARY KEY,-- 主鍵
    ouname VARCHAR(50),-- 部門名稱
		queuenum INT,-- 取號數
		consultnum INT(50), -- 諮詢答覆數量
		linkbnnum INT-- 關聯辦件的數量
	);
	TRUNCATE TABLE tmpTable; 
  OPEN myCursor; -- 開啟遊標  
		myLoop: LOOP -- 開始迴圈體,myLoop為自定義迴圈名
		 FETCH myCursor into ou_name,ou_guid; -- 將遊標當前讀取行的資料,順序賦予自定義變數  
			 IF done=1 THEN -- 判斷是否繼續迴圈  
			 LEAVE myLoop; -- 結束迴圈  
			 END IF;
     
     INSERT INTO tmpTable(rowguid,ouname) values(ou_guid,ou_name);
     END LOOP myLoop; -- 結束自定義迴圈體 
  CLOSE myCursor; -- 關閉遊標  
  select * from tmpTable;
end; 

上面就是在遊標裡面涉及到了兩個變數,並且ou_name和ou_guid是一一對應的

我們可以建立變數向臨時的表裡面輸入資料:

drop procedure if exists pr_dailycheck;
create PROCEDURE pr_dailycheck(in daily1 VARCHAR(32)) 
begin 
declare daily varchar(32);
DECLARE done INT DEFAULT FALSE;
declare ou_guid varchar(50);
declare ou_name varchar(32); 
DECLARE myCursor CURSOR FOR(select ouname,ouguid from frame_ou where oucode like '%320700%');-- 建立遊標並且賦值為結果集合
DECLARE CONTINUE HANDLER for not found SET done = 1;
SET daily=daily1;
CREATE TEMPORARY TABLE IF NOT EXISTS tmpTable 
	(
		rowguid VARCHAR(50) PRIMARY KEY,-- 主鍵
    ouname VARCHAR(50),-- 部門名稱
		queuenum INT,-- 取號數
		consultnum INT(50), -- 諮詢答覆數量
		linkbnnum INT-- 關聯辦件的數量
	);
	TRUNCATE TABLE tmpTable; 
  OPEN myCursor; -- 開啟遊標  
		myLoop: LOOP -- 開始迴圈體,myLoop為自定義迴圈名
		 FETCH myCursor into ou_name,ou_guid; -- 將遊標當前讀取行的資料,順序賦予自定義變數  
			 IF done=1 THEN -- 判斷是否繼續迴圈  
			 LEAVE myLoop; -- 結束迴圈  
			 END IF;
      SET @rowguid=UUID();-- 也可以這樣set @cnt = (select count(*) from test_tbl);
      INSERT INTO tmpTable(rowguid,ouname) values(@rowguid,ou_name);
     END LOOP myLoop; -- 結束自定義迴圈體 
  CLOSE myCursor; -- 關閉遊標  
  select * from tmpTable;
end; 

好了,到這個地方我們的儲存過程在mysql裡面基本上所有的功能都可以實現了,也許上面的描述語句不夠詳細,希望對你有所幫助