练习题:35

目录

Python题目

题目

题目分析

概念理解分析

功能作用分析

执行 SQL 语句功能:

结果集处理功能:

与数据库连接和事务的关联分析

代码实现

1. 查询操作中使用游标

2. 插入操作中使用游标

3. 更新操作中使用游标

4. 删除操作中使用游标

代码解释

查询操作代码解释

导入库与配置参数:

建立连接与创建游标:

执行查询语句并使用游标获取数据:

关闭游标与连接:

异常处理:

插入操作代码解释

更新操作代码解释

删除操作代码解释

运行思路

查询操作(使用游标)运行思路

1. 导入库与配置参数阶段

2. 建立连接与创建游标阶段

3. 执行查询语句阶段

4. 逐行获取并处理数据阶段

5. 关闭游标与连接阶段

6. 异常处理阶段

插入操作(使用游标)运行思路

更新操作(使用游标)运行思路

删除操作(使用游标)运行思路

结束语

Python题目

题目

什么是游标cursor,它有什么作用?

题目分析

  • 概念理解分析

    • 游标定义:在数据库操作中,游标是一个数据库对象,用于遍历查询结果集。可以把游标想象成一个指针,它指向查询结果集中的一条记录。在 Python 中,当使用数据库连接库(如pymysql)与数据库进行交互时,游标对象是在建立数据库连接后创建的,它提供了一系列方法来执行 SQL 语句并处理结果。
  • 功能作用分析

    • 执行 SQL 语句功能
      • 查询操作:游标可以用于执行各种查询语句,如SELECT语句。例如,通过游标执行SELECT * FROM students语句后,数据库会返回一个包含students表中所有记录的结果集,游标就可以用于在这个结果集中进行操作,如逐行获取数据。
      • 数据修改操作:除了查询,游标还能执行数据修改语句,像INSERTUPDATEDELETE等语句。例如,使用游标执行INSERT INTO students (name, age) VALUES ('张三', 20)可以向students表中插入一条新记录。它是数据库操作的一个重要媒介,将 SQL 语句传递给数据库并获取执行后的反馈。
    • 结果集处理功能
      • 逐行获取数据:游标提供了方法来逐行获取查询结果集中的数据。比如在 Python 中使用fetchone()方法,每次调用会返回结果集中的下一条记录,以元组的形式呈现,其中元组的元素对应查询语句中选择列的值。这对于需要逐行处理数据的场景非常有用,如数据清洗、数据验证等操作。
      • 批量获取数据:除了逐行获取,游标还可以使用fetchall()方法一次性获取结果集中的所有数据。当结果集较小且需要整体处理时,这种方式很方便,例如将所有查询到的数据存储到一个列表中进行后续的排序、筛选等操作。
      • 结果集导航与定位:在某些数据库系统和对应的 Python 库支持下,游标还可以用于在结果集中进行导航和定位,如移动到指定的行位置等操作,不过这种功能的使用相对较少,并且不同数据库和库的实现方式可能有所不同。
  • 与数据库连接和事务的关联分析

    • 数据库连接关联性:游标是基于数据库连接创建的,它依赖于连接对象来与数据库进行通信。一个数据库连接可以创建多个游标,不同的游标可以用于执行不同的 SQL 任务,彼此之间相对独立。例如,在一个复杂的数据库应用程序中,可以使用一个游标来执行查询用户信息的操作,同时使用另一个游标来执行更新用户订单状态的操作,它们都共享同一个数据库连接。
    • 事务处理关联性:游标在事务处理过程中也扮演着重要角色。在一个事务中,通过游标执行的多个 SQL 操作可以作为一个整体进行提交(使用commit()函数)或回滚(使用rollback()函数)。例如,在一个转账事务中,通过游标执行从一个账户扣款和向另一个账户收款的两个操作,这两个操作可以放在一个事务中,只有当所有操作都成功执行且事务提交后,数据库中的数据才会真正更新,而游标就是执行这些操作的工具,并且在事务控制过程中起到关键作用。

代码实现

1. 查询操作中使用游标

import pymysql

# 数据库连接配置参数
config = {
    "host": "localhost",
    "user": "root",
    "password": "your_password",
    "database": "your_database",
    "port": 3306
}

try:
    # 建立数据库连接
    connection = pymysql.connect(**config)
    # 创建游标对象
    cursor = connection.cursor()

    # 查询语句
    query_sql = "SELECT * FROM students"
    cursor.execute(query_sql)

    # 逐行获取数据并打印
    row = cursor.fetchone()
    while row is not None:
        print(row)
        row = cursor.fetchone()

    # 关闭游标
    cursor.close()
    # 关闭数据库连接
    connection.close()
except pymysql.Error as e:
    print(f"数据库操作出错: {e}")

2. 插入操作中使用游标

import pymysql

# 数据库连接配置参数
config = {
    "host": "localhost",
    "user": "root",
    "password": "your_password",
    "database": "your_database",
    "port": 3306
}

try:
    # 建立数据库连接
    connection = pymysql.connect(**config)
    # 创建游标对象
    cursor = connection.cursor()

    # 插入语句
    insert_sql = "INSERT INTO students (name, age, gender) VALUES (%s, %s, %s)"
    data = ("李四", 20, "男")
    cursor.execute(insert_sql, data)
    connection.commit()  # 提交事务,使插入生效

    # 关闭游标
    cursor.close()
    # 关闭数据库连接
    connection.close()
except pymysql.Error as e:
    print(f"数据库操作出错: {e}")

3. 更新操作中使用游标

import pymysql

# 数据库连接配置参数
config = {
    "host": "localhost",
    "user": "root",
    "password": "your_password",
    "database": "your_database",
    "port": 3306
}

try:
    # 建立数据库连接
    connection = pymysql.connect(**config)
    # 创建游标对象
    cursor = connection.cursor()

    # 更新语句
    update_sql = "UPDATE students SET age = 22 WHERE name = '李四'"
    cursor.execute(update_sql)
    connection.commit()  # 提交事务,使更新生效

    # 关闭游标
    cursor.close()
    # 关闭数据库连接
    connection.close()
except pymysql.Error as e:
    print(f"数据库操作出错: {e}")

4. 删除操作中使用游标

import pymysql

# 数据库连接配置参数
config = {
    "host": "localhost",
    "user": "root",
    "password": "your_password",
    "database": "your_database",
    "port": 3306
}

try:
    # 建立数据库连接
    connection = pymysql.connect(**config)
    # 创建游标对象
    cursor = connection.cursor()

    # 删除语句
    delete_sql = "DELETE FROM students WHERE name = '李四'"
    cursor.execute(delete_sql)
    connection.commit()  # 提交事务,使删除生效

    # 关闭游标
    cursor.close()
    # 关闭数据库连接
    connection.close()
except pymysql.Error as e:
    print(f"数据库操作出错: {e}")

代码解释

查询操作代码解释

  • 导入库与配置参数
import pymysql

config = {
    "host": "localhost",
    "user": "root",
    "password": "your_password",
    "database": "your_database",
    "port": 3306
}
  • 首先通过 import pymysql 导入用于连接 MySQL 数据库的 pymysql 库。
  • 然后定义 config 字典来存放数据库连接的各项参数,包括数据库服务器地址(host)、登录用户名(user)、登录密码(password)、要连接的数据库名(your_database)以及 MySQL 默认端口号(port)。你需要将这些参数替换为实际有效的信息,以便能正确连接到数据库。
  • 建立连接与创建游标
connection = pymysql.connect(**config)
cursor = connection.cursor()
  • 使用 pymysql.connect(**config) 函数,通过解包 config 字典中的参数来建立与 MySQL 数据库的连接,若连接成功会返回一个 connection 对象,后续操作将基于此对象展开。
  • 接着调用 connection.cursor() 方法从已建立的连接对象中获取游标对象 cursor,游标用于执行具体的 SQL 语句以及获取查询结果。
  • 执行查询语句并使用游标获取数据
query_sql = "SELECT * FROM students"
cursor.execute(query_sql)

row = cursor.fetchone()
while row is not None:
    print(row)
    row = cursor.fetchone()
  • 定义 query_sql 语句,这是一个查询数据的 SQL 语句,用于从名为 students 的表中查询所有记录。
  • 调用 cursor.execute(query_sql) 执行查询操作,游标对象将该查询语句传递给数据库,数据库执行查询并返回结果集。
  • 接着使用 fetchone() 方法通过游标逐行获取结果集中的数据。首先调用 row = cursor.fetchone() 获取结果集中的第一条记录,并将其赋值给变量 row。然后进入 while row is not None: 循环,只要 fetchone() 返回的不是 None,就表示还有数据未读取完,在循环体中通过 print(row) 打印当前行数据(以元组形式呈现,包含表中对应行各列的数据),然后再次调用 row = cursor.fetchone() 获取下一条记录,如此循环,直至读取完所有数据。
  • 关闭游标与连接
cursor.close()
connection.close()

在完成对数据库的查询操作后,为了释放资源并确保数据库连接的正常关闭,需要依次关闭游标对象和数据库连接对象,遵循这样的顺序可以避免资源浪费以及可能出现的数据库连接相关的潜在问题。

  • 异常处理
except pymysql.Error as e:
    print(f"数据库操作出错: {e}")

整个数据库连接和操作的代码被包裹在 try-except 语句块中,用于捕获在使用 pymysql 库连接数据库以及执行 SQL 语句过程中可能出现的各种错误。如果出现错误,比如连接被拒绝、SQL 语法错误等,相应的错误信息会通过 print 函数输出显示,方便排查问题所在,保证程序的健壮性,避免因未处理的异常而意外崩溃。

插入操作代码解释

插入操作代码与查询操作代码在导入库、配置参数、建立连接、创建游标以及关闭游标与连接、异常处理这些部分的逻辑基本一致,以下重点解释插入操作中使用游标执行插入语句的部分:

insert_sql = "INSERT INTO students (name, age, gender) VALUES (%s, %s, %s)"
data = ("李四", 20, "男")
cursor.execute(insert_sql, data)
connection.commit()
  • 定义 insert_sql 语句,这是一个插入数据的 SQL 语句,用于向名为 students 的表中插入一条记录,表中的列包括 nameage 和 gender,使用 %s 作为占位符来表示要插入的具体数据位置,这样可以方便传入动态数据并且有效防止 SQL 注入攻击。
  • 定义 data 变量,它是一个包含要插入数据的元组,按照 insert_sql 语句中占位符的顺序依次对应 nameage 和 gender 的值,这里设定为 ("李四", 20, "男"),你可以根据实际情况修改这些数据。
  • 调用 cursor.execute(insert_sql, data) 执行插入操作,游标对象将插入语句和数据传递给数据库,数据库按照语句要求将数据插入到对应的表和列中。此时插入的数据是在事务缓存区中,还未真正写入数据库。
  • 由于插入操作是对数据库的数据进行修改,对于支持事务的 MySQL 数据库,需要使用 connection.commit() 提交事务,使插入的数据真正生效并持久化存储到数据库中,否则数据只是在事务缓存区中,并未真正写入数据库,后续若出现异常等情况可能导致数据丢失。

更新操作代码解释

更新操作代码同样在前面的基础步骤上与其他操作类似,以下是针对更新操作中使用游标执行更新语句部分的解释:

update_sql = "UPDATE students SET age = 22 WHERE name = '李四'"
cursor.execute(update_sql)
connection.commit()
  • 定义 update_sql 语句,这是一个更新数据的 SQL 语句,用于将 students 表中名为 李四 的学生的年龄更新为 22,通过 WHERE 子句指定了更新的条件。
  • 调用 cursor.execute(update_sql) 执行更新操作,游标对象将更新语句传递给数据库,数据库根据语句要求对符合条件的记录进行相应的字段值更新操作,在事务缓存区中修改对应记录的 age 列的值为 22
  • 同样,因为更新操作涉及数据修改,需要使用 connection.commit() 提交事务,使更新后的结果生效并将修改后的数据持久化存储到数据库中。

删除操作代码解释

删除操作代码的整体结构与其他操作类似,以下是针对删除操作中使用游标执行删除语句部分的解释:

delete_sql = "DELETE FROM students WHERE name = '李四'"
cursor.execute(delete_sql)
connection.commit()
  • 定义 delete_sql 语句,这是一个删除数据的 SQL 语句,用于删除 students 表中名为 李四 的学生记录,通过 WHERE 子句明确了删除的条件。
  • 调用 cursor.execute(delete_sql) 执行删除操作,游标对象将删除语句传递给数据库,数据库根据语句要求将符合条件的记录从数据库表中删除,在事务缓存区中标记这些记录为已删除状态。
  • 最后,由于删除操作也是对数据库数据的修改,需要使用 connection.commit() 提交事务,使删除操作生效,确保记录真正从数据库中被删除。

运行思路

查询操作(使用游标)运行思路

1. 导入库与配置参数阶段
import pymysql

config = {
    "host": "localhost",
    "user": "root",
    "password": "your_password",
    "database": "your_database",
    "port": 3306
}
  • 导入库
    当 Python 解释器执行到 import pymysql 语句时,会在 Python 的模块搜索路径中查找名为 pymysql 的模块,找到后将其加载到内存中,使得后续代码可以调用该模块内定义的各种函数、类等资源,这是后续能够连接 MySQL 数据库并进行操作的基础。若找不到此模块,会抛出 ModuleNotFoundError 异常,导致程序无法继续正常运行。
  • 配置参数
    接着执行定义 config 字典的代码,Python 解释器会在内存中创建一个字典对象,并按照字典语法规则依次将各个键值对存入其中。每个键值对对应数据库连接所需的一个参数,例如 host 键对应的值 "localhost" 表示数据库服务器位于本地;user 键对应的值 "root" 是用于登录数据库的用户名;password 键对应的值 "your_password" 用于验证用户身份;database 键对应的值 "your_database" 明确了要连接的具体数据库;port 键对应的值 3306 是 MySQL 默认的服务端口号,若服务器实际使用其他端口,需相应修改该值,否则可能无法正确连接数据库。配置好这些参数后,为后续建立数据库连接做准备。
2. 建立连接与创建游标阶段
connection = pymysql.connect(**config)
cursor = connection.cursor()
  • 建立连接
    执行 connection = pymysql.connect(**config) 语句时,Python 解释器会调用 pymysql 模块中的 connect 函数,并通过解包 config 字典的方式将参数传递给它。connect 函数内部依据这些参数尝试与指定的 MySQL 数据库建立连接,具体操作如下:
    • 根据 host 参数值定位数据库服务器所在位置,如果是 "localhost" 就在本地查找对应的数据库服务进程,若是远程地址则通过网络协议与远程服务器建立通信链路。
    • 利用 user 和 password 参数提供的用户名和密码向数据库服务器发起身份验证请求,服务器核对信息是否匹配且判断该用户是否有相应访问权限。
    • 依据 database 参 数指定的数据库名称,确定要连接到服务器上的具体数据库实例。
    • 若 port 参数指定的端口号正确,且前面各环节顺利通过,数据库服务器与 Python 程序建立连接,并返回代表该连接的对象,赋值给变量 connection,后续数据库操作基于此对象展开。若过程中出现问题(如服务器不可达、用户名或密码错误等),connect 函数会抛出异常,程序流程跳转到对应的 except 语句块(若有异常处理代码)处理错误。
  • 创建游标
    成功建立连接后,执行 cursor = connection.cursor() 语句,Python 解释器调用连接对象 connection 的 cursor 方法创建游标对象,并赋值给变量 cursor。游标对象如同在数据库内执行操作的 “指针”,后续可通过它执行 SQL 语句并处理返回结果,比如执行查询语句获取数据,或执行修改数据的语句等。
3. 执行查询语句阶段
query_sql = "SELECT * FROM students"
cursor.execute(query_sql)
  • 构建查询语句
    执行到 query_sql = "SELECT * FROM students" 语句时,Python 解释器在内存中创建一个字符串对象,其内容为指定的查询数据的 SQL 语句,表示要从名为 students 的表中查询所有记录。
  • 执行查询操作
    执行 cursor.execute(query_sql) 语句时,Python 解释器调用游标对象 cursor 的 execute 方法,将 query_sql 语句作为参数传入。游标对象内部会把该语句传递给关联的 MySQL 数据库,数据库接收到查询请求后,按照语句要求对 students 表进行检索操作,查找所有记录,并将结果集准备好,等待游标进一步获取数据。
4. 逐行获取并处理数据阶段
row = cursor.fetchone()
while row is not None:
    print(row)
    row = cursor.fetchone()
  • 首次获取数据
    执行 row = cursor.fetchone() 语句时,Python 解释器调用游标对象 cursor 的 fetchone() 方法,该方法向数据库请求获取查询结果集中的第一条记录。若结果集中有数据,数据库将第一条记录(通常为元组形式,元组元素对应查询语句所选列的值)返回给游标对象,再传递给 Python 程序,赋值给变量 row
  • 循环判断与处理数据
    进入 while row is not None: 循环条件判断环节,只要 fetchone() 返回的 row 变量值不为 None,就表明未到结果集末尾,还有数据可读取。在循环体中,先执行 print(row) 语句,Python 解释器将当前获取的记录(以元组形式呈现,包含对应表行各列数据)输出到控制台,也可按需对每行数据做更具体处理(如提取元素赋值给其他变量等)。然后再次执行 row = cursor.fetchone() 语句,继续调用 fetchone() 方法获取下一条记录,更新 row 变量值,为下一次循环判断做准备,如此循环往复,直至 fetchone() 返回 None,表示已读完所有查询结果,循环结束。
5. 关闭游标与连接阶段
cursor.close()
connection.close()
  • 关闭游标
    完成数据库查询操作后,执行 cursor.close() 语句,Python 解释器调用游标对象 cursor 的关闭方法,释放游标对象占用的相关资源,并通知数据库服务器游标使用完毕,进行内部清理操作,确保游标相关资源被正确回收,避免资源浪费及潜在问题(如影响后续数据库连接操作等)。
  • 关闭连接
    接着执行 connection.close() 语句,Python 解释器调用连接对象 connection 的关闭方法,与数据库服务器交互告知连接即将关闭,释放与之相关的所有系统资源,完成数据库连接的正常关闭流程,保障数据库连接资源合理使用及系统稳定运行。
6. 异常处理阶段
except pymysql.Error as e:
    print(f"连接数据库时出现错误: {e}")

整个数据库连接和操作的代码块被包裹在 try-except 语句结构中,用于捕获使用 pymysql 库连接数据库及执行 SQL 语句过程中可能出现的各种错误(如连接被拒绝、SQL 语法错误等)。若出现 pymysql.Error 类型异常,程序流程立即跳转到 except 语句块执行相应错误处理操作,通过 print(f"连接数据库时出现错误: {e}") 将错误信息以格式化字符串形式输出到控制台,方便排查问题,增强程序健壮性,避免因未处理异常而意外崩溃。

插入操作(使用游标)运行思路

插入操作在导入库与配置参数、建立连接与创建游标以及关闭游标与连接、异常处理这些阶段的运行思路与查询操作基本一致,以下重点分析执行插入语句阶段的运行思路:

insert_sql = "INSERT INTO students (name, age, gender) VALUES (%s, %s, %s)"
data = ("李四", 20, "男")
cursor.execute(insert_sql, data)
connection.commit()
  • 构建插入语句与准备数据
    执行到 insert_sql = "INSERT INTO students (name, age, gender) VALUES (%s, %s, %s)" 语句时,Python 解释器在内存中创建一个字符串对象,其内容为指定的插入数据的 SQL 语句,使用 %s 占位符来预留要插入数据的位置,方便后续传入动态数据,同时也能有效防止 SQL 注入攻击,该语句表示要向 students 表中插入一条包含 nameage 和 gender 列信息的新记录。
    接着执行 data = ("李四", 20, "男") 语句,Python 解释器创建一个元组对象,用于存放要插入的数据,且数据顺序与 insert_sql 语句中占位符的顺序对应,分别对应 nameage 和 gender 列的值,这里设定了要插入的新学生的相关信息,你可以根据实际情况修改这些数据。
  • 执行插入操作
    执行 cursor.execute(insert_sql, data) 语句时,Python 解释器调用游标对象 cursor 的 execute 方法,将 insert_sql 语句和 data 作为参数传入。游标对象内部会把这些信息传递给关联的 MySQL 数据库,数据库接收到插入请求后,会识别 %s 占位符,并按照顺序将元组中的参数值(即 "李四"20"男")绑定到对应的列位置,然后尝试将这条新记录插入到 students 表中。此时,插入的数据只是暂存在数据库的事务缓存区中,并没有真正写入数据库,处于一种 “待确认” 状态。
  • 提交事务
    因为 MySQL 数据库是支持事务的,对于插入这样的数据修改操作,执行完操作后需要执行 connection.commit() 语句,Python 解释器调用连接对象 connection 的 commit 方法,将插入的数据真正生效并持久化存储到数据库中,否则数据只是在事务缓存区中,并未真正写入数据库,后续若出现异常等情况可能导致数据丢失。

更新操作(使用游标)运行思路

更新操作在前面基础步骤的运行思路与查询、插入操作类似,以下着重分析执行更新语句阶段的运行思路:

update_sql = "UPDATE students SET age = 22 WHERE name = '李四'"
cursor.execute(update_sql)
connection.commit()
  • 构建更新语句
    执行到 update_sql = "UPDATE students SET age = 22 WHERE name = '李四'" 语句时,Python 解释器在内存中创建一个字符串对象,其内容为指定的更新数据的 SQL 语句,其中 SET age = 22 表示要更新的列及对应的值,WHERE name = '李四' 明确了更新操作的条件,即针对 students 表中名为 李四 的学生记录进行年龄更新操作。
  • 执行更新操作
    执行 cursor.execute(update_sql) 语句时,Python 解释器调用游标对象 cursor 的 execute 方法,将 update_sql 语句作为参数传入。游标对象内部会把该语句传递给关联的 MySQL 数据库,数据库接收到更新请求后,会根据语句中的条件筛选出符合要求(名为 李四)的学生记录,然后在事务缓存区中对这些记录的 age 列进行相应的修改操作,将其值更新为 22。但此时,这些修改只是暂存在事务缓存区中,还未真正应用到数据库的实际存储数据中,同样处于一种 “待确认” 状态。
  • 提交事务
    由于更新操作涉及数据修改,需要执行 connection.commit() 语句,Python 解释器调用连接对象 connection 的 commit 方法,使更新操作在事务缓存区中的修改真正生效并持久化存储到数据库中,确保数据库中对应学生记录的 age 列的值按照更新操作的要求发生实际改变,保证了数据的一致性和准确性。

删除操作(使用游标)运行思路

删除操作在前面常规步骤的运行思路与其他操作类似,以下重点分析执行删除语句阶段的运行思路:

delete_sql = "DELETE FROM students WHERE name = '李四'"
cursor.execute(delete_sql)
connection.commit()
  • 构建删除语句
    执行到 delete_sql = "DELETE FROM students WHERE name = '李四'" 语句时,Python 解释器在内存中创建一个字符串对象,其内容为指定的删除数据的 SQL 语句,通过 WHERE name = '李四' 设置了删除的条件,即针对 students 表中名为 李四 的学生记录进行删除操作。
  • 执行删除操作
    执行 cursor.execute(delete_sql) 语句时,Python 解释器调用游标对象 cursor 的 execute 方法,将 delete_sql 语句作为参数传入。游标对象内部会把该语句传递给关联的 MySQL 数据库,数据库接收到删除请求后,会根据语句中的条件筛选出符合要求(名为 李四)的学生记录,然后在事务缓存区中将这些记录标记为待删除状态,此时这些记录还未从数据库的物理存储中真正删除,同样处于 “待确认” 状态。
  • 提交事务
    因为删除操作也是对数据库数据的修改,所以需要执行 connection.commit() 语句,Python 解释器调用连接对象 connection 的 commit 方法,使删除操作在事务缓存区中的操作真正生效,确保符合条件(名为 李四)的学生记录被从数据库的物理存储中永久性地删除,维护了数据库数据的一致性。

结束语

希望以上对 “什么是游标 cursor,它有什么作用” 这一问题的全面阐释,包括题目剖析、代码实操与运行思路拆解,能让你透彻掌握游标这一关键数据库工具。游标就如同数据库操作舞台上的灵动舞者,在执行 SQL 指令、穿梭结果集、保障事务完整性等诸多环节都展现出无可替代的精妙技艺。无论是面对海量数据的精准检索,还是复杂业务场景下的数据修改,它都能助你优雅应对。在后续的编程探索中,不管是深入挖掘数据库的高级特性,还是致力于构建大型数据驱动项目,凭借对游标的深刻理解,你都将游刃有余。倘若编程途中遭遇数据库相关的疑难,随时回顾这些内容,我也随时待命为你答疑解惑。愿你在编程之路持续奋进,用代码书写更多精彩!

你可能感兴趣的:(练习,oracle,数据库)