详解 rs.open sql,conn,1,1 后数字参数的含义

(1,1为只读数据,1,3为插入数据,2,3是修改数据)

*==========================================================================*
rs.open sql,conn,1,1全接触(已修正)
*==========================================================================*
经常会在连接DB的时候用到:rs.open sql,conn,A,B

A:

adOpenForwardOnly(=0)
只读,且当前数据记录只能向下移动

adOpenKeyset(=1)
只读,当前数据记录可自由移动

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

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

B:

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

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

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

adLockBatchOptimistic(=4)
批量乐观锁定,允许修改多个记录,只有调用UpdateBatch方法后才锁定记录。

当不需要改动任何记录时,应该使用只读的记录集,这样提供者不用做任何检测。
对于一般的使用,乐观的锁定可能是最好的选择,因为记录只被锁定一小段时间,
数据在这段时间被更新。这减少了资源的使用。

*==========================================================================*
详解rs.open sql,conn,1,1后的数字参数的含义
*==========================================================================*
rs.open sql,conn,A,B
参数A为设定游标的类型,其取值为:
0 仅向前游标,只能向前浏览记录,不支持分页、Recordset、BookMark
1 键集游标,其他用户对记录说做的修改将反映到记录集中,但其他用户增加或删除记录不会反映到记录集中。支持分页、Recordset、BookMark
2 动态游标功能最强,但耗资源也最多。用户对记录说做的修改,增加或删除记录都将反映到记录集中。支持全功能浏览。
3 静态游标,只是数据的一个快照,用户对记录说做的修改,增加或删除记录都不会反映到记录集中。支持向前或向后移动


参数B为记录集的锁定类型,其取值为:
1 锁定类型,默认的,只读,不能作任何修改
2 当编辑时立即锁定记录,最安全的方式
3 只有在调用Update方法时才锁定记录集,而在此前的其他操作仍可对当前记录进行更改、插入和删除等
4 当编辑时记录不会被锁定,而更改、插入和删除是在批处理方式下完成的

打开数据记录集方法其实不止一种,但是我们用的最多的就是rs.open sql,1,1的方法,可是后面的数字参数很多人不解其意,下面我们来介绍一下。
其实open方法后面有多个参数
CursorType LockType CommandType
比如 rs.open sql,1,1
也可以写成
rs.cursorType = 1
rs.LockType = 1
rs.open sql
其中CursorType代表从一个表或者一个SQL查询结果返回的记录。
这个参数有四个值分别是:
adOpenForwardOnly 表示只允许在记录集内的记录间往前移动。这个是缺省值。
adOpenKeyset 反映由其它用户所做的对记录的改变或者删除动作,但并不反映由其它用户做作的添加新记录的动作。
adOpenDynamic 反映由其它用户所做的对记录的改变或者删除动作,包括添加的新记录。
adOpenStatic 不反映其它用户对记录所做的修改,添加,删除动作。
这四个值VBSCRIPT预定义为:
adOpenForwardOnly = 0
adOpenKeyset = 1
adOpenDynamic = 2
adOpenStatic = 3

lockType 表示当打开记录集时,数据提供者用于锁定数据库的类型:
adLockReadOnly 数据不能改变,这是缺省值!
adLockPessimistic 数据提供者在开始编辑数据的时候锁定记录。
adLockOptimistic 仅当调用update方法时,数据提供者锁定记录。
adLockBatchOptimistic 用于批处理修改。
他们的常量值定义分别是:
adLockReadOnly = 1
adLockPessimistic = 2
adLockOptimistic = 3
adLockBatchOptimistic = 4

CommandType这个参数由于很少用到,这里就不讲了。

本文转自http://www.360doc.com/content/09/0626/22/19147_4043900.shtml

<think>我们正在处理一个VBA数据库连接问题。用户提供的代码片段是: Set conn1 = CreateObject("ADODB.Connection") 这行代码创建了一个ADODB.Connection对象,用于数据库连接。 但是,用户之前提到需要兼容识别xls表格一起转换,这意味着我们需要一个能够同时处理Access数据库和Excel文件的解决方案。 我们已经有了一个较完整的解决方案,但用户可能希望更详细地了解ADODB.Connection的使用,特别是如何同时兼容Access和Excel。 因此,我将提供一个详细的指南,包括如何创建连接、如何根据文件类型选择连接字符串,以及如何执行查询。 以下是一个完整的VBA模块,它演示了如何使用ADODB.Connection来连接Access数据库和Excel文件,并执行一些基本操作。</think># 深入解析ADODB.Connection对象在VBA中的使用 下面我将详细解释`ADODB.Connection`对象的使用方法,并提供完整的VBA数据库操作解决方案,包括连接管理、数据操作和错误处理。 ## 完整的ADODB连接管理方案 ```vba ' 数据库连接管理器类 ' ============================================== ' 文件名: clsDBConnection.cls ' 功能: 封装数据库连接和操作 ' ============================================== Private m_conn As ADODB.Connection Private m_connectionString As String Private m_isConnected As Boolean ' 初始化连接 Private Sub Class_Initialize() Set m_conn = New ADODB.Connection m_isConnected = False End Sub ' 清理资源 Private Sub Class_Terminate() CloseConnection Set m_conn = Nothing End Sub ' 属性: 连接状态 Public Property Get IsConnected() As Boolean IsConnected = m_isConnected End Property ' 属性: 连接对象 Public Property Get Connection() As ADODB.Connection Set Connection = m_conn End Property ' 创建Access连接字符串 Public Function CreateAccessConnection( _ filePath As String, _ Optional password As String = "", _ Optional engineType As String = "ACE" _ ) As String Dim connStr As String ' 根据引擎类型选择提供程序 If engineType = "ACE" Then connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" Else connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" End If ' 添加数据源 connStr = connStr & "Data Source=" & filePath & ";" ' 添加密码(如果有) If password <> "" Then connStr = connStr & "Jet OLEDB:Database Password=" & password & ";" End If CreateAccessConnection = connStr End Function ' 创建Excel连接字符串 Public Function CreateExcelConnection( _ filePath As String, _ Optional hasHeaders As Boolean = True, _ Optional readOnly As Boolean = False _ ) As String Dim connStr As String Dim ext As String ' 获取文件扩展名 ext = Right(filePath, 4) ' 根据文件类型设置提供程序 connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filePath & ";" ' 添加扩展属性 If LCase(ext) = ".xls" Then connStr = connStr & "Extended Properties=""Excel 8.0;" Else connStr = connStr & "Extended Properties=""Excel 12.0 Xml;" End If ' 添加其他选项 If hasHeaders Then connStr = connStr & "HDR=YES;" Else connStr = connStr & "HDR=NO;" End If If readOnly Then connStr = connStr & "Mode=Read;" Else connStr = connStr & "Mode=ReadWrite;" End If connStr = connStr & "IMEX=1"";" ' 始终将混合数据作为文本读取 CreateExcelConnection = connStr End Function ' 打开数据库连接 Public Sub OpenConnection(connStr As String) On Error GoTo ErrorHandler ' 如果已连接则关闭 If m_isConnected Then CloseConnection End If ' 设置连接字符串 m_connectionString = connStr ' 打开连接 With m_conn .ConnectionString = m_connectionString .ConnectionTimeout = 30 ' 30秒超时 .Open End With m_isConnected = True Exit Sub ErrorHandler: Dim errMsg As String errMsg = "连接错误 [" & Err.Number & "]: " & Err.Description Err.Raise vbObjectError + 1000, "DBConnection.OpenConnection", errMsg End Sub ' 关闭数据库连接 Public Sub CloseConnection() On Error Resume Next ' 防止关闭时出错 If m_isConnected Then If m_conn.State = adStateOpen Then m_conn.Close End If m_isConnected = False End If End Sub ' 执行SQL查询并返回记录集 Public Function ExecuteQuery( _ sql As String, _ Optional cursorType As ADODB.CursorTypeEnum = adOpenStatic, _ Optional lockType As ADODB.LockTypeEnum = adLockReadOnly _ ) As ADODB.Recordset On Error GoTo ErrorHandler Dim rs As New ADODB.Recordset ' 设置记录集属性 rs.CursorLocation = adUseClient rs.CursorType = cursorType rs.LockType = lockType ' 执行查询 rs.Open sql, m_conn, cursorType, lockType, adCmdText ' 返回记录集 Set ExecuteQuery = rs Exit Function ErrorHandler: Dim errMsg As String errMsg = "查询错误 [" & Err.Number & "]: " & Err.Description & vbCrLf & _ "SQL: " & sql Err.Raise vbObjectError + 1001, "DBConnection.ExecuteQuery", errMsg End Function ' 执行非查询SQL(更新、插入、删除) Public Function ExecuteNonQuery(sql As String) As Long On Error GoTo ErrorHandler ' 执行命令 m_conn.Execute sql, ExecuteNonQuery Exit Function ErrorHandler: Dim errMsg As String errMsg = "执行错误 [" & Err.Number & "]: " & Err.Description & vbCrLf & _ "SQL: " & sql Err.Raise vbObjectError + 1002, "DBConnection.ExecuteNonQuery", errMsg End Function ' 开始事务 Public Sub BeginTransaction() If m_isConnected Then m_conn.BeginTrans Else Err.Raise vbObjectError + 1003, "DBConnection.BeginTransaction", "未连接数据库" End If End Sub ' 提交事务 Public Sub CommitTransaction() If m_isConnected Then If m_conn.Properties("Transaction DDL").Value > 0 Then m_conn.CommitTrans End If End If End Sub ' 回滚事务 Public Sub RollbackTransaction() If m_isConnected Then If m_conn.Properties("Transaction DDL").Value > 0 Then m_conn.RollbackTrans End If End If End Sub ' 获取数据库元数据 Public Function GetMetaData(Optional objectType As ADODB.SchemaEnum = adSchemaTables) As ADODB.Recordset On Error GoTo ErrorHandler If Not m_isConnected Then Err.Raise vbObjectError + 1004, "DBConnection.GetMetaData", "未连接数据库" End If Set GetMetaData = m_conn.OpenSchema(objectType) Exit Function ErrorHandler: Dim errMsg As String errMsg = "元数据错误 [" & Err.Number & "]: " & Err.Description Err.Raise vbObjectError + 1004, "DBConnection.GetMetaData", errMsg End Function ``` ## 使用示例 ### 示例1: 连接Access数据库并读取数据 ```vba Sub AccessDatabaseExample() Dim db As New clsDBConnection Dim rs As ADODB.Recordset Dim i As Long On Error GoTo ErrorHandler ' 创建连接字符串 Dim connStr As String connStr = db.CreateAccessConnection("C:\Database\Sample.accdb") ' 打开连接 db.OpenConnection connStr ' 执行查询 Set rs = db.ExecuteQuery("SELECT * FROM Customers") ' 在Excel中显示结果 With ThisWorkbook.Sheets.Add .Name = "Customers" ' 写入列标题 For i = 0 To rs.Fields.Count - 1 .Cells(1, i + 1) = rs.Fields(i).Name Next i ' 写入数据 .Range("A2").CopyFromRecordset rs ' 格式化 .Columns.AutoFit .Rows(1).Font.Bold = True End With ' 清理资源 rs.Close db.CloseConnection MsgBox "数据导入完成!", vbInformation Exit Sub ErrorHandler: MsgBox "错误: " & Err.Description, vbCritical If Not rs Is Nothing Then If rs.State = adStateOpen Then rs.Close End If db.CloseConnection End Sub ``` ### 示例2: 连接Excel文件并更新数据 ```vba Sub ExcelAsDatabaseExample() Dim db As New clsDBConnection Dim rs As ADODB.Recordset On Error GoTo ErrorHandler ' 创建连接字符串 Dim connStr As String connStr = db.CreateExcelConnection("C:\Reports\SalesData.xlsx") ' 打开连接 db.OpenConnection connStr ' 开始事务 db.BeginTransaction ' 执行更新 Dim updateSql As String updateSql = "UPDATE [Sales$] SET Discount = 0.15 " & _ "WHERE Amount > 1000 AND Region = 'North'" Dim rowsAffected As Long rowsAffected = db.ExecuteNonQuery(updateSql) ' 提交事务 db.CommitTransaction ' 验证更新 Set rs = db.ExecuteQuery("SELECT * FROM [Sales$] WHERE Discount = 0.15") MsgBox "更新完成! " & rowsAffected & " 行已更新。" & vbCrLf & _ "找到 " & rs.RecordCount & " 条匹配记录。", vbInformation ' 清理资源 rs.Close db.CloseConnection Exit Sub ErrorHandler: ' 回滚事务 db.RollbackTransaction MsgBox "错误: " & Err.Description, vbCritical If Not rs Is Nothing Then If rs.State = adStateOpen Then rs.Close End If db.CloseConnection End Sub ``` ## ADODB.Connection关键功能解析 ### 1. 连接字符串详解 - **Access连接字符串**: ```vba "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\DB.accdb;" ``` - ACE引擎支持.accdb和.xlsx等新格式 - Jet引擎仅支持.mdb和.xls旧格式 - **Excel连接字符串**: ```vba "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Data.xlsx;" & _ "Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";" ``` - `HDR=YES`:第一行包含列标题 - `IMEX=1`:将混合数据列作为文本读取 ### 2. 事务处理 ```vba ' 开始事务 conn.BeginTrans ' 执行操作 conn.Execute "UPDATE Table SET Value = 100 WHERE ID = 1" ' 提交或回滚 If success Then conn.CommitTrans Else conn.RollbackTrans End If ``` ### 3. 参数化查询(防SQL注入) ```vba Dim cmd As New ADODB.Command With cmd .ActiveConnection = conn .CommandText = "INSERT INTO Users (Name, Email) VALUES (?, ?)" .CommandType = adCmdText ' 添加参数 .Parameters.Append .CreateParameter("Name", adVarChar, adParamInput, 50, "John") .Parameters.Append .CreateParameter("Email", adVarChar, adParamInput, 100, "john@example.com") ' 执行 .Execute End With ``` ### 4. 元数据查询 ```vba ' 获取所有表名 Dim rs As ADODB.Recordset Set rs = conn.OpenSchema(adSchemaTables) ' 获取所有列信息 Set rs = conn.OpenSchema(adSchemaColumns) ``` ## 性能优化技巧 1. **批量插入**: ```vba conn.BeginTrans For i = 1 To 1000 conn.Execute "INSERT INTO Log (Message) VALUES ('Entry " & i & "')" Next i conn.CommitTrans ``` 2. **使用CopyFromRecordset**: ```vba ' 比逐行写入快100倍以上 sheet.Range("A2").CopyFromRecordset rs ``` 3. **连接池管理**: ```vba ' 在应用程序启动时 Set globalConn = New ADODB.Connection globalConn.Open connStr ' 在需要时复用连接 Set rs = globalConn.Execute(sql) ``` 4. **异步操作**: ```vba conn.Execute "LONG_RUNNING_PROCEDURE", , adAsyncExecute ' 检查是否完成 Do While conn.StillExecuting DoEvents Loop ``` ## 常见错误处理 | 错误号 | 原因 | 解决方案 | |--------|------|----------| | -2147217843 | 文件未找到 | 检查文件路径和权限 | | -2147467259 | 无效的提供程序 | 安装正确的数据库引擎 | | 3706 | 提供程序未注册 | 安装Access Database Engine | | -2146824582 | 表不存在 | 检查表名和拼写 | | 3021 | 无当前记录 | 检查记录集是否为空 | ## 高级应用:跨数据库查询 ```vba Sub CrossDatabaseQuery() Dim db As New clsDBConnection Dim connStr As String ' 连接Access数据库 connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MasterDB.accdb;" db.OpenConnection connStr ' 执行跨数据库查询 Dim sql As String sql = "SELECT a.*, b.* " & _ "FROM [Customers] a " & _ "INNER JOIN [Excel 12.0;Database=C:\SalesData.xlsx;HDR=YES].[Q1_Sales$] b " & _ "ON a.CustomerID = b.ClientID" Dim rs As ADODB.Recordset Set rs = db.ExecuteQuery(sql) ' 处理结果... rs.Close db.CloseConnection End Sub ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值