郑成英 發表於 2026-1-9 08:44:37

Python实现调用MySQL数据库的存储过程

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">一、准备工作</a></li><li><a href="#_label1">二、完整实现步骤</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_0">1. 先在 MySQL 中创建测试存储过程</a></li><li><a href="#_lab2_1_1">2. Python 调用存储过程的代码实现</a></li></ul><li><a href="#_label2">三、关键代码解释</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>一、准备工作</h2>
<p>首先需要安装 Python 操作 MySQL 的库,最常用的是 <code>mysql-connector-python</code>(官方库)或 <code>pymysql</code>,这里以官方库为例:</p>
<div class="jb51code"><pre class="brush:bash;">pip install mysql-connector-python
</pre></div>
<p class="maodian"><a name="_label1"></a></p><h2>二、完整实现步骤</h2>
<p class="maodian"><a name="_lab2_1_0"></a></p><h3>1. 先在 MySQL 中创建测试存储过程</h3>
<p>首先我们需要一个可测试的存储过程,比如创建一个根据用户 ID 查询用户信息的存储过程:</p>
<div class="jb51code"><pre class="brush:sql;">-- 先创建测试表(可选)
CREATE TABLE IF NOT EXISTS users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    age INT,
    email VARCHAR(100)
);

-- 插入测试数据
INSERT INTO users (name, age, email) VALUES
('张三', 25, 'zhangsan@test.com'),
('李四', 30, 'lisi@test.com');

-- 创建存储过程:根据ID查询用户信息
DELIMITER //-- 临时修改语句结束符为//,避免与存储过程内的;冲突
CREATE PROCEDURE get_user_by_id(IN user_id INT, OUT user_name VARCHAR(50), OUT user_age INT)
BEGIN
    SELECT name, age INTO user_name, user_age FROM users WHERE id = user_id;
END //
DELIMITER ;-- 恢复语句结束符为;

-- 另一个测试存储过程:无参数,查询所有用户
CREATE PROCEDURE get_all_users()
BEGIN
    SELECT * FROM users;
END;
</pre></div>
<p class="maodian"><a name="_lab2_1_1"></a></p><h3>2. Python 调用存储过程的代码实现</h3>
<p>下面是 Python 调用存储过程的完整代码,包含两种常见场景:<strong>带输入/输出参数的存储过程</strong>、<strong>无参数的存储过程</strong>:</p>
<div class="jb51code"><pre class="brush:py;">import mysql.connector
from mysql.connector import Error

def call_mysql_procedure():
    # 数据库连接配置
    config = {
      'host': 'localhost',       # 数据库地址
      'user': 'root',            # 用户名
      'password': '你的数据库密码', # 密码
      'database': 'test_db'      # 数据库名(替换为你的库名)
    }

    connection = None
    try:
      # 1. 建立数据库连接
      connection = mysql.connector.connect(**config)
      if connection.is_connected():
            cursor = connection.cursor()

            # ========== 场景1:调用带输入/输出参数的存储过程 ==========
            # 定义输入参数和输出参数
            user_id = 1# 输入参数
            user_name = None# 输出参数(初始化为None)
            user_age = None   # 输出参数(初始化为None)

            # 调用存储过程:callproc(存储过程名, (参数列表))
            cursor.callproc('get_user_by_id', (user_id, user_name, user_age))

            # 获取输出参数(存储过程执行后,参数会被更新,存在cursor.stored_results()中)
            for result in cursor.stored_results():
                # 或者直接通过 cursor.outputs 获取(不同版本可能略有差异)
                output_params = result.fetchone()
                if output_params:
                  user_name, user_age = output_params
            print(f"场景1 - 查询ID为{user_id}的用户:")
            print(f"姓名:{user_name},年龄:{user_age}\n")

            # ========== 场景2:调用无参数的存储过程(返回结果集) ==========
            print("场景2 - 查询所有用户:")
            cursor.callproc('get_all_users')# 无参数,传入空元组或省略
            # 遍历结果集
            for result in cursor.stored_results():
                users = result.fetchall()# 获取所有结果
                # 打印表头
                columns = for desc in result.description]
                print("\t".join(columns))
                # 打印数据
                for user in users:
                  print("\t".join(str(col) for col in user))

            # 提交事务(如果存储过程有修改操作,必须提交)
            connection.commit()

    except Error as e:
      print(f"数据库操作出错:{e}")
      # 出错时回滚事务
      if connection:
            connection.rollback()
    finally:
      # 关闭游标和连接
      if connection and connection.is_connected():
            if cursor:
                cursor.close()
            connection.close()
            print("\n数据库连接已关闭")

if __name__ == "__main__":
    call_mysql_procedure()
</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>三、关键代码解释</h2>
<p><strong>1.连接数据库</strong>:通过 <code>mysql.connector.connect()</code> 传入配置参数建立连接,注意替换为你的数据库地址、用户名、密码和库名。</p>
<p><strong>2.调用存储过程核心方法</strong>:<code>cursor.callproc(proc_name, params)</code></p>
<ul><li><code>proc_name</code>:存储过程名称(字符串)。</li><li><code>params</code>:参数列表(元组),顺序需与存储过程的参数(IN/OUT/INOUT)一一对应。</li></ul>
<p><strong>3.获取输出参数/结果集</strong>:</p>
<ul><li>带输出参数的存储过程:执行 <code>callproc</code> 后,通过 <code>cursor.stored_results()</code> 遍历结果,获取输出参数的值。</li><li>返回结果集的存储过程:同样通过 <code>cursor.stored_results()</code> 获取结果集,再用 <code>fetchone()</code>/<code>fetchall()</code> 读取数据。</li></ul>
<p><strong>4.事务处理</strong>:如果存储过程包含插入/更新/删除操作,必须调用 <code>connection.commit()</code> 提交事务;出错时用 <code>connection.rollback()</code> 回滚。</p>
<p><strong>5.资源释放</strong>:最后必须关闭游标和连接,避免资源泄漏。</p>
頁: [1]
查看完整版本: Python实现调用MySQL数据库的存储过程