因為公司最近的一個項目,第一次用到了MySQL(5.10版本),之前聽傳說MySQL很厲害的樣子,因為開源而神奇,但是現在用起來,
感覺並不好啊!我知道是我水平太down,嗚嗚嗚,請各路神仙略施小技,拯救我於水深火熱之中。
本文主要針對以下兩個問題:
(1)存儲過程單個參數傳入值集合。
(2)使用臨時表實現實現對同一結果集的多次使用。
也不說太多廢話了,有下面數據表tb_address和數據,各個地區通過id和parentid實現層級關系:
還有一個表tb_population,記錄了那個區有多少人口,id是主鍵,townid是區的id:
功能一:
現在要實現的功能是通過地區id查詢人口,可以一次查詢多個地區。為了實現這個功能,我創建了一個存儲過程,
但是怎么傳入多個id呢?這個難倒了我,在網上找了不少方法,終於用下面的代碼實現了:
DROP PROCEDURE IF EXISTS pro_getDownPopulation; CREATE PROCEDURE pro_getDownPopulation(ids BLOB) BEGIN
SET @str1 = 'SELECT a.id, a.address, b.population from tb_address a RIGHT JOIN tb_population b on a.id=b.townid WHERE a.id in ('; SET @str2 = ')'; SET @asql = CONCAT(@str1, ids, @str2); PREPARE stmt FROM @asql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
執行該存儲過程pro_getDownPopulation,得到結果如下:
實現是實現了,總感覺有點怪怪的,后來繼續開發的過程中無意間發現有個FIND_IN_SET()函數,果斷用上了,就是不知道性能好不好,
修改后的存儲過程代碼如下:
DROP PROCEDURE IF EXISTS pro_getDownPopulation2; CREATE PROCEDURE pro_getDownPopulation2(ids BLOB) BEGIN SELECT a.id, a.address, b.population from tb_address a RIGHT JOIN tb_population b on a.id=b.townid WHERE FIND_IN_SET(a.id, ids); END;
執行該存儲過程pro_getDownPopulation2,得到結果如下:(注意兩次傳入參數的格式的不同)
我的兩種實現方式就是這樣,到底哪種好,沒有經過性能方面的測試,還請大家指教!
功能二:
按地方的層級(省、市、區)統計個地方的人口,並以樹的結構顯示統計結果(軟件端顯示)。因為有一個簡單的結果集我要反復用到,
所以我使用了臨時表,但是在網上查到的說法:同一個query里同一個臨時表只能使用一次,故創建了多個相同結果的臨時表,代碼如下:
DROP PROCEDURE IF EXISTS pro_population_statistics; CREATE PROCEDURE pro_population_statistics() BEGIN
DROP TEMPORARY TABLE IF EXISTS tempTable1; DROP TEMPORARY TABLE IF EXISTS tempTable2; DROP TEMPORARY TABLE IF EXISTS tempTable3; CREATE TEMPORARY TABLE tempTable1 SELECT a.id shengID, a.address sheng, b.id shiID, b.address shi, c.id quID, c.address qu, d.population FROM tb_address a LEFT JOIN tb_address b on a.id = b.parentid LEFT JOIN tb_address c on b.id = c.parentid LEFT JOIN tb_population d on c.id = d.townid WHERE a.parentid=''; CREATE TEMPORARY TABLE tempTable2 SELECT * from tempTable1; CREATE TEMPORARY TABLE tempTable3 SELECT * from tempTable1; SELECT sheng, SUM(population) population from tempTable1 GROUP BY shengID UNION
SELECT shi, SUM(population) from tempTable2 GROUP BY shiID UNION
SELECT qu, population from tempTable3; END;
執行存儲過程pro_population_statistics,結果如下:
功能是實現了,但是我存在很多疑惑的地方,特別是同一個query里同一個臨時表只能使用一次,
我使用多個臨時表,用起來性能比較差,大家有什么解決的方法嗎?
我還有另外一個疑問:在一個存儲過程里如何調用另外一個存儲過程並保存后者返回的結果集?
很少寫文章,排版上的問題請大家多多包涵and多多指導,謝謝!