首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 預存程序完整指南:建立、參數模式、變數、流程控制與 Java/JDBC 呼叫實戰

     編輯:MySQL 綜合教學

MySQL 預存程序完整指南

預存程序將業務邏輯封裝在資料庫層,減少網路往返、提升安全性與維護性。本文系統整理建立/修改/刪除/查看語法、IN/OUT/INOUT 參數模式、變數宣告、流程控制、動態 SQL,並附 Java JDBC 呼叫完整範例。

核心語法速查

操作語法
建立CREATE PROCEDURE name([IN|OUT|INOUT] param type) BEGIN ... END
修改ALTER PROCEDURE name ...
刪除DROP PROCEDURE [IF EXISTS] name
查看定義SHOW CREATE PROCEDURE name
列出所有SHOW PROCEDURE STATUS
呼叫CALL name([params])

參數模式詳解

模式方向初始值用途
IN呼叫者 → 程序呼叫者提供輸入參數,程序內修改不影響外部
OUT程序 → 呼叫者NULL輸出參數,程序內賦值返回
INOUT雙向呼叫者提供輸入並經處理後輸出

實戰範例

-- 1. 輸出參數:取得員工總數
DROP PROCEDURE IF EXISTS proc_emp_count;
CREATE PROCEDURE proc_emp_count(OUT total INT)
BEGIN
    SELECT COUNT(*) INTO total FROM employee;
END;

CALL proc_emp_count(@total);
SELECT @total;

-- 2. 輸入參數:依 ID 查詢員工
DROP PROCEDURE IF EXISTS proc_emp_by_id;
CREATE PROCEDURE proc_emp_by_id(IN emp_id INT)
BEGIN
    SELECT * FROM employee WHERE id = emp_id;
END;

SET @id = 1;
CALL proc_emp_by_id(@id);
-- 或 CALL proc_emp_by_id(1);

-- 3. INOUT:傳入基數,返回平方
DROP PROCEDURE IF EXISTS proc_square;
CREATE PROCEDURE proc_square(INOUT num INT)
BEGIN
    SET num = num * num;
END;

SET @n = 5;
CALL proc_square(@n);
SELECT @n;  -- 25

變數與流程控制

-- 區域變數宣告(必須在 BEGIN 區塊開頭)
DECLARE v_count INT DEFAULT 0;
DECLARE v_name VARCHAR(50);

-- 賦值
SET v_count = 10;
SET v_name = 'Tom';

-- SELECT INTO
SELECT COUNT(*), MAX(name) INTO v_count, v_name FROM employee;

-- 條件判斷
IF v_count > 0 THEN
    SELECT '有資料';
ELSEIF v_count = 0 THEN
    SELECT '無資料';
ELSE
    SELECT '異常';
END IF;

-- 迴圈
WHILE v_count < 10 DO
    SET v_count = v_count + 1;
END WHILE;

-- 游標(略)

定界符變更(客戶端建立時必須)

DELIMITER //

CREATE PROCEDURE demo()
BEGIN
    SELECT 1;
END //

DELIMITER ;

Java JDBC 呼叫完整範例

import java.sql.*;

public class StoredProcDemo {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/test?useSSL=false";
        String user = "root", pass = "123456";
        
        try (Connection conn = DriverManager.getConnection(url, user, pass)) {
            // 1. 呼叫輸入參數程序
            try (CallableStatement cs = conn.prepareCall("{CALL proc_emp_by_id(?)}")) {
                cs.setInt(1, 1);
                try (ResultSet rs = cs.executeQuery()) {
                    while (rs.next()) {
                        System.out.println(rs.getInt("id") + "\t" + rs.getString("name"));
                    }
                }
            }
            
            // 2. 呼叫輸出參數程序
            try (CallableStatement cs = conn.prepareCall("{CALL proc_emp_count(?)}")) {
                cs.registerOutParameter(1, Types.INTEGER);
                cs.execute();
                System.out.println("總員工數:" + cs.getInt(1));
            }
            
            // 3. 呼叫 INOUT 程序
            try (CallableStatement cs = conn.prepareCall("{CALL proc_square(?)}")) {
                cs.setInt(1, 7);
                cs.registerOutParameter(1, Types.INTEGER);
                cs.execute();
                System.out.println("平方:" + cs.getInt(1));  // 49
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

注意事項

  • 刪除程序不帶括號:DROP PROCEDURE name
  • 建立/呼叫必須帶括號:CREATE PROCEDURE name() / CALL name()
  • 參數名避免與資料欄位同名,否則產生歧義
  • MySQL 5.0+ 才支援預存程序,舊版本不可用
  • 過度使用預存程序會增加資料庫 CPU 壓力,建議核心業務邏輯才用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved