ADO 排序

ADO 排序(Sort)简介

ADO(ActiveX Data Objects) 中,排序(Sort)是指对 Recordset 对象中的记录按指定字段进行升序(ASC)或降序(DESC)排列。ADO 提供 Sort 属性,允许在客户端游标(adUseClient)下动态对记录集进行排序,无需修改 SQL 查询。这对于在经典 ASP、VBA、VB6 或 Python(通过 pywin32)中处理数据库查询结果非常有用。

本教程聚焦 ADO 的排序功能,详细讲解 Sort 属性的用法、步骤和注意事项,并结合上下文(如 REST API、ChromeDriver、Cron、Traefik、列表推导式)提供实用示例。假设你已熟悉 ADO 的 ConnectionRecordset查询(参考前文)。


一、ADO 排序核心概念

  • Sort 属性
  • 用于对 Recordset 中的记录按一个或多个字段排序。
  • 语法:rs.Sort = "Field1 [ASC|DESC], Field2 [ASC|DESC]"
  • 仅在客户端游标(rs.CursorLocation = 3adUseClient)下有效,因为服务端游标依赖数据库引擎排序。
  • SQL 排序
  • 替代方法:在 SQL 查询中使用 ORDER BY 子句。
  • 适用于所有游标类型,但需要重新执行查询。
  • 适用场景
  • 动态调整前端显示顺序(ASP 网页)。
  • 处理临时排序需求(无需修改 SQL)。
  • 结合过滤、分页显示排序后的数据。

二、ADO 排序用法

1. 使用 Recordset.Sort 属性

要求

  • 设置 rs.CursorLocation = 3(adUseClient)。
  • Recordset 必须打开且为可排序游标(adOpenStaticadOpenKeyset)。

ASP 示例(按公司名称升序排序):

<%@ Language=VBScript %>
<html>
<head>
    <title>ADO 排序</title>
</head>
<body>
    <h2>客户列表(按公司名称升序)</h2>
    <table border="1">
        <tr>
            <th>公司名称</th>
            <th>联系人</th>
        </tr>
<%
    ' 创建连接和记录集
    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.CursorLocation = 3  ' adUseClient
    rs.Open "SELECT CompanyName, ContactName FROM Customers", conn, 3, 1  ' adOpenStatic, adLockReadOnly

    ' 排序
    rs.Sort = "CompanyName ASC"

    ' 显示记录
    Do Until rs.EOF
        Response.Write "<tr>"
        Response.Write "<td>" & Server.HTMLEncode(rs("CompanyName")) & "</td>"
        Response.Write "<td>" & Server.HTMLEncode(rs("ContactName")) & "</td>"
        Response.Write "</tr>"
        rs.MoveNext
    Loop

    ' 清理资源
    rs.Close
    conn.Close
    Set rs = Nothing
    Set conn = Nothing
%>
    </table>
</body>
</html>
  • 输出:HTML 表格显示按 CompanyName 升序排列的客户列表。
  • 关键点
  • rs.CursorLocation = 3 启用客户端游标。
  • rs.Sort = "CompanyName ASC" 按公司名称升序排序。
  • 调试(类似 console.log)Response.Write rs.Fields("CompanyName").Value

多字段排序

rs.Sort = "Country ASC, CompanyName DESC"
  • 先按国家升序,再按公司名称降序。

2. 使用 SQL ORDER BY

直接在 SQL 查询中使用 ORDER BY,适用于所有游标类型。

ASP 示例

rs.Open "SELECT CompanyName, ContactName FROM Customers ORDER BY CompanyName ASC", conn, 3, 1
  • 优点:数据库引擎优化排序,适合大数据集。
  • 缺点:更改排序需重新执行查询。

3. Python(通过 pywin32)

安装 pywin32

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

示例:按公司名称排序并显示

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.CursorLocation = 3  # adUseClient
rs.Open("SELECT CompanyName, ContactName FROM Customers", conn, 3, 1)  # adOpenStatic, adLockReadOnly

# 排序
rs.Sort = "CompanyName ASC"

# 显示记录
print(f"{'Company':<30} {'Contact':<20}")
print("-" * 50)
while not rs.EOF:
    print(f"{str(rs.Fields('CompanyName').Value):<30} {str(rs.Fields('ContactName').Value):<20}")
    rs.MoveNext()

# 清理资源
rs.Close()
conn.Close()
  • 输出
  Company                       Contact
  --------------------------------------------------
  Alfreds Futterkiste          Maria Anders
  Ana Trujillo Emparedados     Ana Trujillo
  ...
  • 调试print(repr(rs.Fields))print(str(rs.Fields("CompanyName").Value))

三、结合上下文的应用

  1. 结合 REST API
  • 返回排序后的 JSON 数据。 <% 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.CursorLocation = 3 rs.Open "SELECT CompanyName, ContactName FROM Customers", conn, 3 rs.Sort = "CompanyName ASC" 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 = win32com.client.Dispatch("ADODB.Recordset") rs.CursorLocation = 3 rs.Open("SELECT CompanyName, ContactName FROM Customers", conn, 3) rs.Sort = "CompanyName ASC" 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 页面(排序后的 Recordset 数据)。
    python from selenium.webdriver import Chrome driver = Chrome() driver.get('http://localhost/test.asp') # ASP 使用 Sort 显示排序表格 print(driver.find_element(By.TAG_NAME, 'table').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 = win32com.client.Dispatch("ADODB.Recordset") rs.CursorLocation = 3 rs.Open("SELECT CompanyName FROM Customers", conn, 3) rs.Sort = "CompanyName ASC" with open('sorted_customers.txt', 'w') as f: for _ in tqdm(range(rs.RecordCount), desc="Sorting"): if not rs.EOF: f.write(f"{str(rs.Fields('CompanyName').Value)}\n") rs.MoveNext() conn.Close()
    • 保存为 ado_sort.py,通过 Windows 任务计划程序运行。
  1. 结合 Traefik
  • Traefik 代理 ASP 网站(排序后的 Recordset 数据)。
    yaml services: asp: image: my-asp-app labels: - "traefik.http.routers.asp.rule=Host(`asp.example.com`)" - "traefik.http.routers.asp.entrypoints=websecure"
  1. 结合列表推导式
  • 处理排序后的 Recordset 数据。
    python 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.CursorLocation = 3 rs.Open("SELECT CompanyName FROM Customers", conn, 3) rs.Sort = "CompanyName ASC" names = [str(rs.Fields("CompanyName").Value) for _ in range(rs.RecordCount) if not rs.EOF and (rs.MoveNext() or True)] print(f"Sorted Names: {repr(names)}") conn.Close()
  1. 结合 ==is
  • 检查 Recordset 状态:
    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. 游标要求
  • Sort 属性需要 rs.CursorLocation = 3(adUseClient)。
  • 使用 adOpenStaticadOpenKeyset 游标,否则报错。
  1. 性能
  • Sort 在客户端操作,适合小数据集;大数据集建议 SQL ORDER BY
  • 限制查询范围(如 SELECT TOP 10)。
  1. 错误处理
  • ASP:
    asp On Error Resume Next rs.Sort = "NonExistentColumn" If Err.Number <> 0 Then Response.Write "错误:" & Err.Description
  • Python:
    python try: rs.Sort = "NonExistentColumn" except Exception as e: print(f"Error: {e}")
  1. 调试(类似 console.log)
  • ASP:Response.Write rs.Fields(0).Value.
  • Python:print(repr(rs.Fields)).
  1. SQL ORDER BY 替代
  • 如果不需要动态排序,SQL ORDER BY 更高效:
    python rs.Open("SELECT CompanyName FROM Customers ORDER BY CompanyName ASC", conn)
  1. 现代替代
  • Python:pyodbcsqlalchemy
  • .NET:ADO.NET 或 Entity Framework.

五、总结

  • ADO 排序:通过 rs.Sort(客户端游标)或 SQL ORDER BY 实现记录排序。
  • 关键步骤:设置客户端游标、打开记录集、应用 Sort、遍历显示。
  • 结合上下文
  • REST API:返回排序后的 JSON。
  • ChromeDriver:测试排序页面。
  • Cron:定时输出排序结果。
  • Traefik:代理 ASP 服务。
  • 列表推导式:处理排序数据。
  • 调试:使用 Response.Write(ASP)或 print(repr())(Python)。

如果需要更复杂的排序(如多字段、分页结合)或特定调试帮助,请提供更多细节!

类似文章

发表回复

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