ADO 更新记录
ADO 更新记录(Update Record)简介
在 ADO(ActiveX Data Objects) 中,更新记录是指通过 Recordset 对象的 Update
方法或通过 Connection/Command
对象的 Execute
方法修改数据库表中的现有记录。这在经典 ASP、VBA、VB6 或 Python(通过 pywin32
)等环境中常用于更新用户信息、订单状态等操作。
本教程聚焦 ADO 的记录更新功能,详细讲解 Recordset.Update
和 SQL UPDATE
的用法,并结合上下文(如 REST API、ChromeDriver、Cron、Traefik、列表推导式)提供实用示例。假设你已熟悉 ADO 的 Connection、Recordset、查询 和 添加记录(参考前文)。
一、ADO 更新记录核心概念
- 方法:
- Recordset.Update:定位记录,修改字段值后保存。
- Connection.Execute:执行 SQL
UPDATE
语句,直接更新记录。 - Command.Execute:使用参数化
UPDATE
语句,防止 SQL 注入。 - 要求:
- Recordset 需使用可编辑游标(如
adOpenKeyset=1
或adOpenDynamic=2
)和可写锁(如adLockOptimistic=3
或adLockPessimistic=2
)。 - 数据库表需允许更新(检查权限和表结构)。
- 定位记录:
- 使用
Find
方法或 SQLWHERE
子句定位要更新的记录。 - 适用场景:
- Web 表单修改数据(如 ASP 页面更新用户)。
- 批量更新记录(Python 脚本)。
- 定时任务更新状态(Cron/任务计划程序)。
二、ADO 更新记录方法
1. 使用 Recordset.Update
要求:
- 游标类型:
adOpenKeyset
或adOpenDynamic
。 - 锁类型:
adLockOptimistic
或adLockPessimistic
。 - 使用
Find
或循环定位记录,修改字段后调用Update
。
ASP 示例(更新客户公司名称):
<%@ Language=VBScript %>
<html>
<head>
<title>ADO 更新记录</title>
</head>
<body>
<h2>更新客户</h2>
<%
' 创建连接和记录集
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Northwind.mdb"
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open "Customers", conn, 1, 3 ' adOpenKeyset, adLockOptimistic
' 定位记录
rs.Find "CustomerID='ALFKI'"
If Not rs.EOF Then
rs("CompanyName") = "Updated Corp"
rs("ContactName") = "Maria Updated"
rs.Update
Response.Write "更新成功!"
Else
Response.Write "记录未找到!"
End If
' 清理资源
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
%>
</body>
</html>
- 关键点:
rs.Open "Customers", conn, 1, 3
:使用可编辑游标和锁。rs.Find
:定位记录(支持简单条件,如CustomerID='ALFKI'
)。rs.Update
:保存更改。- 调试(类似 console.log):
Response.Write rs("CompanyName")
.
2. 使用 Connection.Execute(SQL UPDATE)
直接执行 SQL UPDATE
语句,适合简单更新。
ASP 示例:
<%
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Northwind.mdb"
conn.Execute "UPDATE Customers SET CompanyName='New Corp', ContactName='Jane Updated' WHERE CustomerID='ALFKI'"
Response.Write "更新成功!"
conn.Close
Set conn = Nothing
%>
- 关键点:
- 简单但不安全(易受 SQL 注入)。
- 不返回记录集,适合非查询操作。
3. 使用 Command.Execute(参数化更新)
参数化查询防止 SQL 注入,适合动态输入。
ASP 示例:
<%
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Northwind.mdb"
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = "UPDATE Customers SET CompanyName=?, ContactName=? WHERE CustomerID=?"
cmd.Parameters.Append cmd.CreateParameter("CompanyName", 200, 1, 40, "New Corp 2") ' adVarChar
cmd.Parameters.Append cmd.CreateParameter("ContactName", 200, 1, 30, "John Updated")
cmd.Parameters.Append cmd.CreateParameter("CustomerID", 200, 1, 5, "ALFKI")
cmd.Execute
Response.Write "参数化更新成功!"
conn.Close
Set conn = Nothing
%>
- 关键点:
adVarChar=200
:指定参数类型。- 更安全,适合用户输入。
4. Python(通过 pywin32)
安装 pywin32
:
pip install pywin32 -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
示例:使用 Recordset.Update
import win32com.client
# 创建连接和记录集
conn = win32com.client.Dispatch("ADODB.Connection")
conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb")
rs = win32com.client.Dispatch("ADODB.Recordset")
rs.Open("Customers", conn, 1, 3) # adOpenKeyset, adLockOptimistic
# 定位并更新记录
rs.Find("CustomerID='ALFKI'")
if not rs.EOF:
rs.Fields("CompanyName").Value = "Updated Corp Python"
rs.Fields("ContactName").Value = "Maria Python"
rs.Update()
print("更新成功!")
else:
print("记录未找到!")
# 清理资源
rs.Close()
conn.Close()
- 调试:
print(repr(rs.Fields))
或print(str(rs.Fields("CompanyName").Value))
.
示例:参数化更新
import win32com.client
conn = win32com.client.Dispatch("ADODB.Connection")
conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb")
cmd = win32com.client.Dispatch("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = "UPDATE Customers SET CompanyName=?, ContactName=? WHERE CustomerID=?"
cmd.Parameters.Append(cmd.CreateParameter("CompanyName", 200, 1, 40, "New Corp Python 2"))
cmd.Parameters.Append(cmd.CreateParameter("ContactName", 200, 1, 30, "John Python"))
cmd.Parameters.Append(cmd.CreateParameter("CustomerID", 200, 1, 5, "ALFKI"))
cmd.Execute()
print("参数化更新成功!")
conn.Close()
三、结合上下文的应用
- 结合 REST API:
- ASP:通过表单更新记录,返回 JSON 确认。
<% If Request.Form("submit") <> "" Then Set conn = Server.CreateObject("ADODB.Connection") conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Northwind.mdb" Set rs = Server.CreateObject("ADODB.Recordset") rs.Open "Customers", conn, 1, 3 rs.Find "CustomerID='" & Request.Form("customer_id") & "'" If Not rs.EOF Then rs("CompanyName") = Request.Form("company") rs("ContactName") = Request.Form("contact") rs.Update Response.ContentType = "application/json" Response.Write "{""status"":""success""}" Else Response.Write "{""status"":""not found""}" End If rs.Close conn.Close End If %> <form method="post"> Customer ID: <input name="customer_id"><br> Company: <input name="company"><br> Contact: <input name="contact"><br> <input type="submit" name="submit" value="Update"> </form>
- Python(Flask):
from flask import Flask, request, jsonify import win32com.client app = Flask(__name__) @app.route('/customers/<customer_id>', methods=['PUT']) def update_customer(customer_id): conn = win32com.client.Dispatch("ADODB.Connection") conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb") rs = win32com.client.Dispatch("ADODB.Recordset") rs.Open("Customers", conn, 1, 3) rs.Find(f"CustomerID='{customer_id}'") if not rs.EOF: rs.Fields("CompanyName").Value = request.json["company"] rs.Fields("ContactName").Value = request.json["contact"] rs.Update() conn.Close() return jsonify({"status": "success"}) conn.Close() return jsonify({"status": "not found"}), 404
- 结合 ChromeDriver 和 Selenium:
- 测试 ASP 表单(更新记录后验证页面)。
python from selenium.webdriver import Chrome from selenium.webdriver.common.by import By driver = Chrome() driver.get('http://localhost/update_customer.asp') driver.find_element(By.NAME, 'customer_id').send_keys('ALFKI') driver.find_element(By.NAME, 'company').send_keys('Updated Corp Selenium') driver.find_element(By.NAME, 'contact').send_keys('Maria Selenium') driver.find_element(By.NAME, 'submit').click() print(driver.find_element(By.TAG_NAME, 'body').text) # 检查结果 driver.quit()
- 结合 Linux Cron(Windows 任务计划程序):
- 定时批量更新记录。
python import win32com.client from tqdm import tqdm updates = [ {"CustomerID": "ALFKI", "CompanyName": "Batch Corp 1", "ContactName": "Maria Batch"}, {"CustomerID": "ANATR", "CompanyName": "Batch Corp 2", "ContactName": "Ana Batch"} ] conn = win32com.client.Dispatch("ADODB.Connection") conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb") rs = win32com.client.Dispatch("ADODB.Recordset") rs.Open("Customers", conn, 1, 3) for update in tqdm(updates, desc="Updating customers"): rs.Find(f"CustomerID='{update['CustomerID']}'") if not rs.EOF: rs.Fields("CompanyName").Value = update["CompanyName"] rs.Fields("ContactName").Value = update["ContactName"] rs.Update() print("批量更新完成!") rs.Close() conn.Close()
- 保存为
ado_update.py
,通过 Windows 任务计划程序运行。
- 保存为
- 结合 Traefik:
- Traefik 代理 ASP 网站(更新记录的表单)。
yaml services: asp: image: my-asp-app labels: - "traefik.http.routers.asp.rule=Host(`asp.example.com`)" - "traefik.http.routers.asp.entrypoints=websecure"
- 结合列表推导式:
- 批量更新记录并验证。
python import win32com.client updates = [ {"CustomerID": "ALFKI", "CompanyName": "List Corp 1", "ContactName": "Maria List"}, {"CustomerID": "ANATR", "CompanyName": "List Corp 2", "ContactName": "Ana List"} ] conn = win32com.client.Dispatch("ADODB.Connection") conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb") rs = win32com.client.Dispatch("ADODB.Recordset") rs.Open("Customers", conn, 1, 3) [rs.Find(f"CustomerID='{u['CustomerID']}'") or (not rs.EOF and [rs.Fields(k).Update(v) for k, v in u.items() if k != "CustomerID"] and rs.Update()) for u in updates] print("更新完成!") rs.Close() conn.Close()
- 结合
==
和is
:
- 检查记录集状态:
python if rs.State == 1: # 值比较 print("Recordset open") if rs is not None: # 身份比较 print("Recordset exists")
- 结合
str()
和repr()
:
- 调试更新的记录:
python rs.MoveLast() print(str(rs.Fields("CompanyName").Value)) # 用户友好 print(repr(rs.Fields("CompanyName").Value)) # 调试
四、注意事项
- 游标和锁类型:
- 必须使用
adOpenKeyset
或adOpenDynamic
和adLockOptimistic
/adLockPessimistic
。 - 否则报错:
Operation is not allowed in this context
.
- 字段约束:
- 确保字段值符合数据库约束(如长度、类型)。
- 检查必填字段和外键关系。
- SQL 注入:
- 避免拼接用户输入:
asp ' 错误示例 conn.Execute "UPDATE Customers SET CompanyName='" & Request("company") & "' WHERE CustomerID='ALFKI'"
- 错误处理:
- ASP:
asp On Error Resume Next rs.Update If Err.Number <> 0 Then Response.Write "错误:" & Err.Description
- Python:
python try: rs.Update() except Exception as e: print(f"Error: {e}")
- 调试(类似 console.log):
- ASP:
Response.Write rs.Fields("CompanyName").Value
. - Python:
print(repr(rs.Fields))
.
- 性能:
- 批量更新使用事务(
conn.BeginTrans
,conn.CommitTrans
)。 - 避免频繁打开/关闭 Recordset。
- 现代替代:
- Python:
pyodbc
或sqlalchemy
. - .NET:ADO.NET 或 Entity Framework.
五、总结
- ADO 更新记录:通过
Recordset.Update
、SQLUPDATE
或Command.Execute
修改记录。 - 关键步骤:定位记录(
Find
或WHERE
)、修改字段、保存更改。 - 结合上下文:
- REST API:处理表单更新,返回 JSON。
- ChromeDriver:测试更新表单。
- Cron:定时批量更新。
- Traefik:代理 ASP 服务。
- 列表推导式:批量更新记录。
- 调试:使用
Response.Write
(ASP)或print(repr())
(Python)。
如果需要更复杂的更新场景(如事务、批量优化)或特定调试帮助,请提供更多细节!