CONN.EXECUTE(SQL,RowsAffected,C) 和 RS.OPEN SQL,CONN,A,B,C 参数说明

本文详细解释了 ADO 中 RS.Open 和 Conn.Execute 方法的参数含义,包括读取模式、锁定类型和 SQL 命令类型的设置,以及如何通过这些参数优化数据库操作的性能。

wzcount = conn.execute ("select count(id) from `table1`",0,1)(0)

请问execute后面两个参数是什么意思?最后的那个0是什么意思? 还有哦···

set conn = server.createobject("adodb.connection")

set rs = server.createobject("adodb.recordset")

rs.open rssql,conn,1,1,&h0001

  解答:1.RS.OPEN SQL,CONN,A,B,C

              2.CONN.EXECUTE(SQL,RowsAffected,C)

              参数含义:SQL的值可以是SQL语句、表名、存储过程名,也可以是数据提供者所能接受的任意字符串。为了提高性能,最好为C参数指定合适的值可选参数RowsAffected将返回INSERT、UPDATE或DELETE查询执行以后所影响的数目。这些查询会返回一个关闭的Recordset对象。一个SELECT查询将返回RowsAffected值为-1并且返回带有一行或多行内容的打开的Recordset。

EX:

<%set Conn=Server.CreateObject("ADODB.Connection")

   Conn.open "Provider=SQLOLEDB;Password=xiaolu;User ID=sa;Database=Test;Data Source =127.0.0.1"

conn.execute "update Table1 set Col1='123'",RowsAffected,&H0001

Response.Write RowsAffected&" 行受到影响"

Conn.close

Set Conn=Nothing%>

A: ADOPENFORWARDONLY(=0) 只读,且当前数据记录只能向下移动ADOPENKEYSET(=1) 只读,当前数据记录可自由移动

ADOPENDYNAMIC(=2) 可读写,当前数据记录可自由移动

ADOPENSTATIC(=3) 可读写,当前数据记录可自由移动,可看到新增记录

B:ADLOCKREADONLY(=1) 缺省锁定类型,记录集是只读的,不能修改记录

ADLOCKPESSIMISTIC(=2) 悲观锁定,当修改记录时,数据提供者将尝试锁定记录以确保成功地编辑记录。只要编辑一开始,则立即锁住记录。

ADLOCKOPTIMISTIC(=3) 乐观锁定 ,直到用Update方法提交更新记录时才锁定记录。

ADLOCKBATCHOPTIMISTIC(=4) 批量乐观锁定,允许修改多个记录,只有调用UpdateBatch方法后才锁定记录。当不需要改动任何记录时,应该使用只读的记录集,这样提供者不用做任何检测。对于一般的使用,乐观的锁定可能是最好的选择,因为记录只被锁定一小段时间,数据在这段时间被更新。这减少了资源的使用。

C:(指定SQL语句类型)

ADCmdUnknown (= &H0008)未知,需要系统来判断,速度慢,为缺省值

ADCmdText (= &H0001)命令语句如SQL语句如:Select * from Table1ADCmdTable (= &H0002)查询的表名称,例如:Table1

ADCmdStoredProc (= &H0004)存储过程名称

ADCmdFile (= &H0100)对象类型相应的文件名称

ADCmdTableDirect (= &H0200)是能直接从表中获取行内容的表名称

你给出的 `execute` 方法代码是用于执行写入型 SQL 语句(如 `INSERT`、`UPDATE`、`DELETE`)的一个典型实现。我们来**详细分析这段代码**,指出其优点、潜在问题,并提供优化建议完整解释。 --- ### ✅ 原始代码 ```python def execute(self, sql: str, params: tuple | None): with self.conn.cursor(cursor=pymysql.cursors.DictCursor) as cursor: cursor.execute(sql, params or ()) self.conn.commit() return cursor.rowcount ``` --- ## 🔍 代码逐行解析 ```python def execute(self, sql: str, params: tuple | None): ``` - 定义一个方法,接收: - `sql`: 要执行的 SQL 字符串。 - `params`: 可选的参数元组,用于防止 SQL 注入(推荐做法)。 - 类型提示使用了现代 Python 的 `|` 语法(Python 3.10+),表示 `params` 可以是 `tuple` 或 `None`。 ```python with self.conn.cursor(cursor=pymysql.cursors.DictCursor) as cursor: ``` - 使用上下文管理器创建游标。 - **问题点**:这里指定了 `DictCursor` —— 这通常是为 `SELECT` 查询设计的,返回字典形式的结果。 - 对于 `INSERT/UPDATE/DELETE` 等写操作,其实不需要返回字段名,用普通 `Cursor` 更高效。 ```python cursor.execute(sql, params or ()) ``` - 执行 SQL。 - 如果 `params` 是 `None`,则替换为空元组 `()`,避免传 `None` 导致错误。 ```python self.conn.commit() ``` - 提交事务,使更改持久化。 - 正确地在执行后提交。 ```python return cursor.rowcount ``` - 返回受影响的行数(例如:更新了几条记录、删除了多少行等),非常有用! --- ## ⚠️ 存在的问题与改进建议 | 问题 | 说明 | 改进方案 | |------|------|---------| | 使用 `DictCursor` 处理写操作 | 浪费性能,因为 `DictCursor` 会解析列名,但写操作不关心结果结构 | 改用默认游标(`pymysql.cursors.Cursor`) | | 没有异常处理 | 若 SQL 出错,连接不会回滚,可能导致数据不一致 | 加上 `try-except` 并回滚 | | 直接使用 `self.conn` | 假设 `self.conn` 已存在且有效,缺乏连接管理健壮性 | 推荐封装连接获取逻辑(如前文 `get_connection()` 上下文管理器) | --- ## ✅ 优化后的版本 ```python # database.py import pymysql from typing import Tuple, Optional from contextlib import contextmanager class Database: def __init__(self, host: str, port: int, user: str, password: str, database: str): self.config = { 'host': host, 'port': port, 'user': user, 'password': password, 'database': database, 'charset': 'utf8mb4', 'autocommit': False } @contextmanager def get_connection(self): conn = None try: conn = pymysql.connect(**self.config) yield conn except Exception as e: if conn: conn.rollback() raise e finally: if conn: conn.close() def execute(self, sql: str, params: Optional[Tuple] = None) -> int: """ 执行单条写入SQLINSERT/UPDATE/DELETE),返回影响行数 :param sql: SQL语句 :param params: 参数元组,防止SQL注入 :return: 影响的行数 """ with self.get_connection() as conn: with conn.cursor() as cursor: # 使用默认 Cursor,更高效 try: cursor.execute(sql, params or ()) affected_rows = cursor.rowcount conn.commit() return affected_rows except Exception as e: conn.rollback() raise RuntimeError(f"数据库执行失败: {sql}, 错误: {e}") from e ``` --- ## ✅ 使用示例 ```python db = Database(host="localhost", port=3306, user="root", password="123456", database="test_db") # 插入数据 sql_insert = "INSERT INTO users (name, email) VALUES (%s, %s)" rows = db.execute(sql_insert, ("Alice", "alice@example.com")) print(f"插入了 {rows} 行") # 更新数据 sql_update = "UPDATE users SET email = %s WHERE name = %s" rows = db.execute(sql_update, ("new_email@example.com", "Alice")) print(f"更新了 {rows} 行") ``` --- ## ✅ 为什么不用 `DictCursor`? - `DictCursor` 主要用于查询时希望得到 `{column: value}` 字典格式。 - 写操作不需要解析列名,使用默认 `Cursor` 性能更高、资源消耗更低。 > ✅ 建议:只在 `query()` 方法中使用 `DictCursor`,在 `execute()` 中使用默认游标。 --- ## ✅ 补充:什么时候该用 `commit()`?什么时候不该? | 场景 | 是否手动 commit | |------|----------------| | `INSERT`, `UPDATE`, `DELETE` | ✅ 必须 commit | | `SELECT` | ❌ 不需要 commit | | 启用了 `autocommit=True` | 可省略 commit,但不推荐用于批量操作 | | 需要事务控制(多条SQL一起成功或失败) | 手动控制 commit / rollback | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值