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

MySQL 儲存過程開發與 Python callproc 調用實戰指南

     編輯:MySQL 綜合教學

儲存過程將 SQL 邏輯下沉至資料庫層,減少網路往返、利用預編譯提升性能、封裝業務規則。本文涵蓋語法、參數模式、流程控制、Python mysql-connector 調用全流程(含 OUT/INOUT 參數獲取技巧)。

一、儲存過程核心語法

DELIMITER $$
CREATE PROCEDURE proc_name (
  IN  p_in_param   INT,      -- 輸入
  OUT p_out_param  INT,      -- 輸出
  INOUT p_io_param INT       -- 輸入輸出
)
BEGIN
  -- 邏輯體
  SELECT COUNT(*) INTO p_out_param FROM orders WHERE status = p_in_param;
  SET p_io_param = p_io_param + p_in_param;
END$$
DELIMITER ;

二、參數模式詳解

模式調用時體內可讀體內可寫返回給調用者
IN必須傳值✅❌❌
OUT傳變量名(如 @v)❌✅✅
INOUT傳已賦值變量✅✅✅

調用示例

-- IN + OUT
CALL GetOfficeByCountry('USA', @total);
SELECT @total;

-- INOUT 累加器
SET @counter = 1;
CALL set_counter(@counter, 1);  -- 2
CALL set_counter(@counter, 5);  -- 7
SELECT @counter;  -- 7

三、流程控制結構

-- IF
IF cond THEN stmts; [ELSEIF cond THEN stmts;] [ELSE stmts;] END IF;

-- CASE
CASE val WHEN v1 THEN stmts; WHEN v2 THEN stmts; ELSE stmts; END CASE;

-- WHILE
label: WHILE cond DO stmts; END WHILE label;
LEAVE label;  -- break
ITERATE label; -- continue

-- REPEAT / LOOP
REPEAT stmts; UNTIL cond END REPEAT;
label: LOOP stmts; END LOOP label;

四、Python mysql-connector 調用全流程

from mysql.connector import MySQLConnection, Error
from python_mysql_dbconfig import read_db_config  # 自定義配置讀取

def call_find_all_sp():
    try:
        db_config = read_db_config()
        conn = MySQLConnection(**db_config)
        cursor = conn.cursor()

        # 1. 調用無參數過程
        cursor.callproc('find_all')

        # 2. 獲取多個結果集
        for result in cursor.stored_results():
            rows = result.fetchall()
            print(rows)  # 業務處理

        # 3. 調用帶 OUT/INOUT 參數的過程
        # cursor.callproc('proc_name', ['in_val', 0, 0])  # 佔位符
        # OUT/INOUT 值在服務端會話變量 @_proc_name_索引
        # 索引對應參數聲明順序(從 0 開始)
        cursor.execute("SELECT @_proc_name_1, @_proc_name_2")
        out_vals = cursor.fetchone()
        print("OUT params:", out_vals)

    except Error as e:
        print(f"Error: {e}")
    finally:
        cursor.close()
        conn.close()

if __name__ == '__main__':
    call_find_all_sp()

五、OUT/INOUT 參數獲取關鍵技巧

callproc() 不直接返回 OUT/INOUT 值,MySQL 將其存放於用戶會話變量:

  • 命名規則:@_procedure_name_param_index(索引從 0 開始,對應 CREATE PROCEDURE 參數順序)。
  • 調用後額外執行 SELECT @_proc_0, @_proc_1 ... 獲取。
# 過程:CREATE PROCEDURE p(IN a INT, OUT b INT, INOUT c INT)
cursor.callproc('p', [10, 0, 100])  # 佔位 0/100
cursor.execute("SELECT @_p_1, @_p_2")  # b=OUT(索引1), c=INOUT(索引2)
out_b, inout_c = cursor.fetchone()

六、最佳實踐與避坑

  1. 業務邊界:核心事務邏輯(扣款、庫存扣減)適合下沉;複雜報表/異構計算留應用層。
  2. 事務控制:過程內不建議顯式 COMMIT/ROLLBACK,由調用方控制邊界(除非自治事務)。
  3. 權限最小化:調用布號僅授予 EXECUTE ON PROCEDURE db.proc TO 'app'@'%'。
  4. 版本管理:DDL 腳本納入遷移工具,避免手動修改導致不一致。
  5. 調試技巧:SELECT ... INTO @debug_var + SELECT @debug_var,或寫入日志表。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved