MySQL 存儲過程 自定義函數

本文已轉到我的博客空間  明月工做室http://www.freebytes.net/it/database/mysql-cunchu.htmlhtml

一. 定義

        存儲過程 Procedure 是一組爲了完成特定功能的 SQL 語句集合,經編譯後存儲在數據庫中,用戶經過指定存儲過程的名稱並給出參數來執行。存儲過程當中能夠包含邏輯控制語句和數據操縱語句,它能夠接受參數、輸出參數、返回單個或多個結果集以及返回值。java

        以上是官方的定義。簡單來講,若是把sql當成是代碼,其實存儲過程就至關於函數。把一組具有特定功能的sql語句封裝成起來而已。因此他的本質是爲了更好的執行對數據庫的操做。那麼好在哪裏呢?mysql

二. 存儲過程的優點

        1. 性能。存儲過程在建立時就已經在數據庫服務器中編譯好並存儲起來,調用時只需提供過程名和參數,就能夠直接使用。而sql語句,沒執行一句就要編譯一次,這在sql語句發送並不頻繁的狀況下還好,可是若是短期大量發送sql語句的狀況下,不只會下降網絡性能也會增長數據庫負擔。sql

        2. 可完成更復雜的數據庫控制。因爲存儲過程當中能夠包含邏輯控制語句和數據操縱語句,相似遍歷、if這種邏輯能夠直接卸載過程當中。數據庫

        3.我在程序中寫了一段代碼,發送一千條sql插入語句到本地數據庫,大概花了6672ms,而在存儲過程當中只花了4689ms。如下分別是代碼和存儲過程sql:服務器

@Autowired
    private JdbcTemplate jdbcTemplate;

    public static final String INSERT_SQL="insert into user (id, name, age) values(?,?,?)";

    public void insert(){
        long begin = System.currentTimeMillis();
        for (int i = 600000; i < 601000; i++) {
            jdbcTemplate.update(INSERT_SQL,i,"林"+i,10+Math.random()*10);
        }
        long end = System.currentTimeMillis();
        System.out.println(end-begin);
    }
CREATE PROCEDURE test_insert2 () 

BEGIN
DECLARE i INT DEFAULT 601000;
WHILE i<602000
DO
insert into `user` (id,NAME,age) values (i,CONCAT('林',i),18); 
SET i=i+1;
END WHILE;
COMMIT;
END;

CALL test_insert2()

三. 存儲過程基本語法和變量講解

        1. delimiter //     該語句指定MySQL把「//」看成分隔符。也就是說,若是你在MySQL client中輸入這句,則「;」符號再也不被看成結束符。網絡

        2. create procedure getAllUser()    表示建立存儲過程,其名爲getAllUser()。dom

        3. call getAllUser ;       調用存儲過程getAllUser。函數

        4. drop procedure getAllUser;   刪除存儲過程。性能

        5. begin...end  之間編寫過程體,即寫sql語句和邏輯代碼。

        6. 存儲過程根據須要可能會有輸入、輸出、輸入輸出參數,若是有多個參數用","分割開。MySQL存儲過程的參數用在存儲過程的定義,共有三種參數類型,IN,OUT,INOUT:

  • IN參數的值必須在調用存儲過程時指定,在存儲過程當中修改該參數的值不能被返回,爲默認值
  • OUT:該值可在存儲過程內部被改變,並可返回
  • INOUT:調用時指定,而且可被改變和返回

四. 分別在MySQL client中和Navicat中建立存儲過程

  • 在client建立一個查詢全部user表記錄的過程。

        

        最後輸入 還原分隔符爲 「;」

        調用過程

        刪除過程

  • 在Navicat中建立一個插入user表數據的存儲過程 ,而且傳遞兩個參數

        

        右鍵新建函數,選擇過程

        

        

        在這裏寫邏輯語句吧,完整以下:

BEGIN

DECLARE i INT DEFAULT initValue;
WHILE i<=endValue
DO
insert into `user` (id,NAME,age) values (i,CONCAT('林',i),18); 
SET i=i+1;
END WHILE;
COMMIT;

END

        這裏的意思是 把第一個參數賦給變量i,當i小於第二個參數值時,一直進行while循環,每次循環i+1。

  Navicat裏面點擊sql預覽能夠看到完整的代碼:

 按下ctrl+s保存:

而後運行,輸入兩個參數,逗號隔開:

就能夠插入數據了。

五. 在java程序中調用存儲過程

@Autowired
    private DataSource dataSource;
    public List<User> getUser() {
        List<User> users = new ArrayList<User>(10000);
        User user = new User();
        try {
            CallableStatement callableStatement = dataSource.getConnection().prepareCall("{call getUser}");
            ResultSet rs = null; //執行查詢操做,並獲取結果集
            rs = callableStatement.executeQuery();
            while (rs.next()){
                user.setName(rs.getString("name"));
                user.setAge(rs.getInt("age"));
                user.setId(rs.getInt("id"));
                users.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return users;
    }

調用一個getUser()的存儲過程,並將結果封裝成實體。主要是 CallableStatement callableStatement = dataSource.getConnection().prepareCall("{call getUser}");這句代碼。這裏我認爲應該有更成熟的調用方式纔對,可是我也懶得找資料了。反正原理都同樣。

六. 自定義函數

mysql的自定義函數其實就是咱們本身去定義相似sum(...)、max(...)這種函數,很簡單,建立起來跟存儲過程差很少,就很少作講解了。

create function sum1(x int,y int) returns int(20)

begin 

        //編寫函數體

return xxx ;

end ; 

使用  select sum1(215,555)

刪除  drop sum1

相關文章
相關標籤/搜索