ADO 查询

ADO 查询(Query)简介

ADO(ActiveX Data Objects) 中,查询是通过 RecordsetCommand 对象执行 SQL 语句,从数据库中检索数据或执行操作(如插入、更新、删除)。ADO 查询是数据库交互的核心功能,支持 SQL 语言,适用于经典 ASP、VBA、VB6 和 Python(通过 pywin32)等环境。查询结果通常存储在 Recordset 中,用于后续显示或处理。

本教程聚焦 ADO 查询的实现,涵盖 SQL 查询、参数化查询、执行方式,并结合上下文(如 REST API、ChromeDriver、Cron、Traefik、列表推导式)提供实用示例。假设你已熟悉 ADO 的 ConnectionRecordset(参考前文)。


一、ADO 查询核心概念

  • 查询类型
  • SELECT:检索数据,返回 Recordset。
  • INSERT/UPDATE/DELETE:修改数据,返回受影响行数(通过 CommandConnection.Execute)。
  • 存储过程:调用数据库预定义过程。
  • 执行方式
  • Recordset.Open:直接打开记录集,适合 SELECT 查询。
  • Connection.Execute:执行 SQL,返回记录集或受影响行数。
  • Command.Execute:支持参数化查询,防止 SQL 注入。
  • 关键对象
  • Connection:提供数据库连接。
  • Recordset:存储查询结果。
  • Command:执行带参数的 SQL 语句。

二、ADO 查询方式

1. 使用 Recordset.Open

直接通过 Recordset 执行 SELECT 查询,适合简单场景。

ASP 示例(查询客户):

<%
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 "SELECT CompanyName, ContactName FROM Customers WHERE Country='USA'", conn, 3, 1  ' adOpenStatic, adLockReadOnly

Do Until rs.EOF
    Response.Write Server.HTMLEncode(rs("CompanyName")) & "<br>"
    rs.MoveNext
Loop

rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
%>
  • 关键点
  • rs.Open sql, conn, cursorType, lockTypecursorType=3(adOpenStatic),lockType=1(adLockReadOnly)适合只读查询。
  • Server.HTMLEncode:防止 XSS 攻击。
  • 调试(类似 console.log)Response.Write rs.Fields("CompanyName").Value.

2. 使用 Connection.Execute

通过 Connection 对象直接执行 SQL,适合简单查询或非 SELECT 语句。

ASP 示例(插入记录):

<%
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Northwind.mdb"

conn.Execute "INSERT INTO Customers (CustomerID, CompanyName) VALUES ('XYZ', 'XYZ Corp')"

Response.Write "插入成功!"
conn.Close
Set conn = Nothing
%>
  • 关键点
  • 返回受影响行数(可选:conn.Execute sql, affectedRows)。
  • 不适合复杂查询(推荐 Recordset 或 Command)。

3. 使用 Command 对象(参数化查询)

参数化查询防止 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 = "SELECT * FROM Customers WHERE Country=?"
Set param = cmd.CreateParameter("@Country", 200, 1, 50, "USA")  ' adVarChar
cmd.Parameters.Append param

Set rs = cmd.Execute
Do Until rs.EOF
    Response.Write rs("CompanyName") & "<br>"
    rs.MoveNext
Loop

rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
%>
  • 关键点
  • adVarChar=200:指定参数类型。
  • 更安全,避免拼接 SQL 字符串。

4. Python(通过 pywin32)

安装 pywin32

pip install pywin32 -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com

示例:SELECT 查询

import win32com.client

conn = win32com.client.Dispatch("ADODB.Connection")
conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb")

rs = conn.Execute("SELECT CompanyName, ContactName FROM Customers WHERE Country='USA'")[0]
while not rs.EOF:
    print(str(rs.Fields("CompanyName").Value))
    rs.MoveNext()

rs.Close()
conn.Close()
  • 关键点
  • conn.Execute 返回元组,[0] 是 Recordset。
  • 使用 str() 格式化输出(参考 str() vs repr())。

示例:参数化查询

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 = "SELECT * FROM Customers WHERE Country=?"
cmd.Parameters.Append(cmd.CreateParameter("Country", 200, 1, 50, "USA"))

rs = cmd.Execute()[0]
while not rs.EOF:
    print(str(rs.Fields("CompanyName").Value))
    rs.MoveNext()

rs.Close()
conn.Close()

三、结合上下文的应用

  1. 结合 REST API
  • 返回 JSON 格式的查询结果。
    asp <% Response.ContentType = "application/json" 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 "SELECT CompanyName, ContactName FROM Customers", conn Response.Write "[" first = True Do Until rs.EOF If Not first Then Response.Write "," Response.Write "{""company"":""" & Server.HTMLEncode(rs("CompanyName")) & """,""contact"":""" & Server.HTMLEncode(rs("ContactName")) & """}" first = False rs.MoveNext Loop Response.Write "]" rs.Close conn.Close %>
  • Python(Flask)from flask import Flask, jsonify import win32com.client app = Flask(__name__) @app.route('/customers') def get_customers(): conn = win32com.client.Dispatch("ADODB.Connection") conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb") rs = conn.Execute("SELECT CompanyName, ContactName FROM Customers")[0] customers = [{"company": str(rs.Fields("CompanyName").Value), "contact": str(rs.Fields("ContactName").Value)} for _ in range(rs.RecordCount) if not rs.EOF and (rs.MoveNext() or True)] conn.Close() return jsonify(customers)
  1. 结合 ChromeDriver 和 Selenium
  • 测试 ASP 页面(ADO 查询生成)。
    python from selenium.webdriver import Chrome driver = Chrome() driver.get('http://localhost/test.asp') # ASP 使用 ADO 查询 print(driver.find_element(By.TAG_NAME, 'body').text) driver.quit()
  1. 结合 Linux Cron(Windows 任务计划程序)
  • 定时运行查询脚本,输出到文件。 python import win32com.client from tqdm import tqdm conn = win32com.client.Dispatch("ADODB.Connection") conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb") rs = conn.Execute("SELECT CompanyName FROM Customers")[0] with open('customers.txt', 'w') as f: for _ in tqdm(range(rs.RecordCount), desc="Querying"): if not rs.EOF: f.write(f"{str(rs.Fields('CompanyName').Value)}\n") rs.MoveNext() conn.Close()
    • 保存为 ado_query.py,通过 Windows 任务计划程序运行。
  1. 结合 Traefik
  • Traefik 代理 ASP 网站(ADO 查询提供数据)。
    yaml services: asp: image: my-asp-app labels: - "traefik.http.routers.asp.rule=Host(`asp.example.com`)" - "traefik.http.routers.asp.entrypoints=websecure"
  1. 结合列表推导式
  • 处理查询结果。
    python import win32com.client conn = win32com.client.Dispatch("ADODB.Connection") conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb") rs = conn.Execute("SELECT CompanyName FROM Customers")[0] names = [str(rs.Fields("CompanyName").Value) for _ in range(rs.RecordCount) if not rs.EOF and (rs.MoveNext() or True)] print(f"Names: {repr(names)}") conn.Close()
  1. 结合 ==is
  • 检查查询结果:
    python if rs.State == 1: # 值比较 print("Recordset open") if rs is not None: # 身份比较 print("Recordset exists")
  1. 结合 str()repr()
  • 格式化输出:
    python while not rs.EOF: print(str(rs.Fields("CompanyName").Value)) # 用户友好 print(repr(rs.Fields("CompanyName").Value)) # 调试 rs.MoveNext()

四、注意事项

  1. SQL 注入
  • 避免直接拼接用户输入,使用参数化查询(Command 对象)。
  • 错误示例rs.Open "SELECT * FROM Customers WHERE Country='" & Request("country") & "'", conn(易受注入攻击)。
  1. 性能优化
  • 使用 SELECT column1, column2 而非 SELECT *
  • 设置客户端游标(rs.CursorLocation = 3)支持 RecordCount
  • 分页查询(如 SELECT TOP 10)。
  1. 错误处理
  • ASP:
    asp On Error Resume Next rs.Open "SELECT * FROM NonExistentTable", conn If Err.Number <> 0 Then Response.Write "错误:" & Err.Description
  • Python:
    python try: rs = conn.Execute("SELECT * FROM NonExistentTable")[0] except Exception as e: print(f"Error: {e}")
  1. 调试(类似 console.log)
  • ASP:Response.Write rs.Fields(0).Value.
  • Python:print(repr(rs.Fields)).
  1. 现代替代
  • Python:pyodbcsqlalchemy
  • .NET:ADO.NET 或 Entity Framework.

五、总结

  • ADO 查询:通过 Recordset、Connection.Execute 或 Command 执行 SQL,获取或修改数据。
  • 关键方式
  • Recordset.Open:简单 SELECT。
  • Connection.Execute:非 SELECT 或简单查询。
  • Command.Execute:参数化查询,安全高效。
  • 结合上下文
  • REST API:返回 JSON。
  • ChromeDriver:测试查询结果页面。
  • Cron:定时查询。
  • Traefik:代理 ASP 服务。
  • 列表推导式:处理查询结果。
  • 调试:使用 Response.Write(ASP)或 print(repr())(Python)。

如果需要特定查询示例(如复杂 JOIN、分页)、存储过程调用或调试帮助,请提供更多细节!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注