VB中更新SQL 数据出错 (在线等,满意即结贴)

还有人用VB6吗 2010-04-21 04:05:54
Set lRs = New ADODB.Recordset

lRs.Open "select * from [Temp]", cN, adOpenStatic, adLockOptimistic
Do While (Not lRs.EOF)
lRs.Fields("内障率").Value = 123
lRs.Update
lRs.MoveNext
Loop

lRs.Close

执行到 lRs.Update 语句时报错 “键列信息不足或不正确。更新影响到多行。”
...全文
213 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
chinaboyzyq 2010-04-22
  • 打赏
  • 举报
回复
Open 方法 (ADO Recordset)


打开游标。

语法

recordset.Open Source, ActiveConnection, CursorType, LockType, Options

参数

Source 可选,变体型,计算 Command 对象的变量名、SQL 语句、表名、存储过程调用或持久 Recordset 文件名。

ActiveConnection 可选。变体型,计算有效 Connection 对象变量名;或字符串,包含 ConnectionString 参数。

CursorType 可选,CursorTypeEnum 值,确定提供者打开 Recordset 时应该使用的游标类型。可为下列常量之一(参阅 CursorType 属性可获得这些设置的定义)。

常量 说明
AdOpenForwardOnly (默认值)打开仅向前类型游标。
AdOpenKeyset 打开键集类型游标。
AdOpenDynamic 打开动态类型游标。
AdOpenStatic 打开静态类型游标。


LockType 可选。确定提供者打开 Recordset 时应该使用的锁定(并发)类型的 LockTypeEnum 值,可为下列常量之一(参见 LockType 属性可获得详细信息)。

常量 说明
AdLockReadOnly (默认值)只读 — 不能改变数据。
AdLockPessimistic 保守式锁定(逐个) — 提供者完成确保成功编辑记录所需的工作,通常通过在编辑时立即锁定数据源的记录。
AdLockOptimistic 开放式锁定(逐个) — 提供者使用开放式锁定,只在调用Update 方法时才锁定记录。
AdLockBatchOptimistic 开放式批更新—用于批更新模式(与立即更新模式相对)。


Options 可选,长整型值,用于指示提供者如何计算 Source 参数(如果它代表的不是 Command 对象),或从以前保存 Recordset 的文件中恢复 Recordset。可为下列常量之一(参见 CommandType 属性可获得该列表中前五个常量的详细说明)。

常量 说明
adCmdText 指示提供者应该将 Source 作为命令的文本定义来计算。
adCmdTable 指示 ADO 生成 SQL 查询以便从在 Source 中命名的表中返回所有行。
adCmdTableDirect 指示提供者更改从在 Source 中命名的表中返回所有行。
adCmdStoredProc 指示提供者应该将 Source 视为存储过程。
adCmdUnknown 指示 Source 参数中的命令类型为未知。
adCmdFile 指示应从在 Source 中命名的文件中恢复保留(保存的)Recordset。
adAsyncExecute 指示应异步执行 Source。
adAsyncFetch 指示在提取 Initial Fetch Size 属性中指定的初始数量后,应该异步提取所有剩余的行。如果所需的行尚未提取,主要的线程将被堵塞直到行重新可用。
adAsyncFetchNonBlocking 指示主要线程在提取期间从未堵塞。如果所请求的行尚未提取,当前行自动移到文件末尾。
chinaboyzyq 2010-04-22
  • 打赏
  • 举报
回复
UpdateBatch 方法


将所有挂起的批更新写入磁盘。

语法

recordset.UpdateBatch AffectRecords

参数

AffectRecords 可选,AffectEnum 值。决定 UpdateBatch 方法所影响的记录数目。可以为如下常量之一。

常量 说明
adAffectCurrent 只写入当前记录的挂起更改。
adAffectGroup 写入满足当前 Filter 属性设置的记录所发生的挂起更改。必须将 Filter 属性设置为某个有效的预定义常量才能使用该选项。
adAffectAll (默认值)。写入 Recordset 对象中所有记录的挂起更改,包括由于当前 Filter 属性设置而隐藏的任何记录。
adAffectAllChapters 写入所有子集的挂起更改。


说明

按批更新模式修改 Recordset 对象时,使用 UpdateBatch 方法可将 Recordset 对象中的所有更改传递到基本数据库。

如果 Recordset 对象支持批更新,那么可以将一个或多个记录的多重更改缓存在本地,然后再调用 UpdateBatch 方法。如果在调用 UpdateBatch 方法时正在编辑当前记录或者添加新的记录,那么在将批更新传送到提供者之前,ADO 将自动调用 Update 方法保存对当前记录的所有挂起更改。

注意 只能对键集或静态游标使用批更新。

如果由于与基本的数据冲突而导致对所有或任意记录的传送更改失败(如其他用户已将记录删除),那么提供者将把警告返回给 Errors 集合,并发生运行时错误。使用 Filter 属性 (adFilterAffectedRecords) 和 Status 属性可以找到发生冲突的记录。

要取消所有挂起的批更新,请使用 CancelBatch 方法。

如果设置了 Unique Table 和 Update Resync 动态属性,并且 Recordset 是对多个表执行 JOIN 操作的结果,那么,取决于 Update Resync 属性,执行 UpdateBatch 方法会隐性导致 Resync 方法。
chinaboyzyq 2010-04-22
  • 打赏
  • 举报
回复
数据表中没有自增长ID字段,且数据表中有重复的记录,才会报这样的错误。
还有人用VB6吗 2010-04-22
  • 打赏
  • 举报
回复
刚才根据myhongye 回答的试验了一下,还是跳出报错,但按照他的方法换成UpdateBatch就通过了
这是绍明原因呢?
Do While (Not lRs.EOF)
lRs.Fields("内障率").Value = 123

lRs.MoveNext
Loop
lRs.UpdateBatch adAffectAllChapters

另外,adAffectCurrent,adAffectGroup ,adAffectAllChapters 三个常数代表什么意义?

lRs.Open "select * from [Temp]", cN, adOpenKeyset, adLockOptimistic 语句中

adOpenStatic与adOpenKeyset有什么不同, adLockOptimistic呢?

红叶哥 2010-04-22
  • 打赏
  • 举报
回复
adOpenStatic 向前游标
adOpenKeyset 键集游标
adLockOptimistic设置窗口为固定的大小

附带一个小资料:
-----------------------------------
常数 常数值 说明
-----------------------------------
adOpenForwardOnly 0 缺省值,启动一个只能向前移动的游标(Forward Only)。
adOpenKeyset 1 启动一个Keyset类型的游标。
adOpenDynamic 2 启动一个Dynamic类型的游标。
adOpenStatic 3 启动一个Static类型的游标。
-----------------------------------
以上几个游标类型将直接影响到Recordset对象所有的属性和方法,以下列表说明他们之间的区别。

---------------------------------------------
Recordset属性 adOpenForwardOnly adOpenKeyset adOpenDynamic adOpenStatic
---------------------------------------------
AbsolutePage 不支持 不支持 可读写 可读写
AbsolutePosition 不支持 不支持 可读写 可读写
ActiveConnection 可读写 可读写 可读写 可读写
BOF 只读 只读 只读 只读
Bookmark 不支持 不支持 可读写 可读写
CacheSize 可读写 可读写 可读写 可读写
CursorLocation 可读写 可读写 可读写 可读写
CursorType 可读写 可读写 可读写 可读写
EditMode 只读 只读 只读 只读
EOF 只读 只读 只读 只读
Filter 可读写 可读写 可读写 可读写
LockType 可读写 可读写 可读写 可读写
MarshalOptions 可读写 可读写 可读写 可读写
MaxRecords 可读写 可读写 可读写 可读写
PageCount 不支持 不支持 只读 只读
PageSize 可读写 可读写 可读写 可读写
RecordCount 不支持 不支持 只读 只读
Source 可读写 可读写 可读写 可读写
State 只读 只读 只读 只读
Status 只读 只读 只读 只读
AddNew 支持 支持 支持 支持
CancelBatch 支持 支持 支持 支持
CancelUpdate 支持 支持 支持 支持
Clone 不支持 不支持
Close 支持 支持 支持 支持
Delete 支持 支持 支持 支持
GetRows 支持 支持 支持 支持
Move 不支持 支持 支持 支持
MoveFirst 支持 支持 支持 支持
MoveLast 不支持 支持 支持 支持
MoveNext 支持 支持 支持 支持
MovePrevious 不支持 支持 支持 支持
NextRecordset 支持 支持 支持 支持
Open 支持 支持 支持 支持
Requery 支持 支持 支持 支持
Resync 不支持 不支持 支持 支持
Supports 支持 支持 支持 支持
Update 支持 支持 支持 支持
UpdateBatch 支持 支持 支持 支持
----------------------------------------
其中NextRecordset方法并不适用于Microsoft Access数据库。

LockType
Recordset对象Open方法的LockType参数表示要采用的Lock类型,如果忽略这个参数,那么系统会以Recordset对象的LockType属性为预设值。LockType参数包含adLockReadOnly、adLockPrssimistic、adLockOptimistic及adLockBatchOptimistic等,分述如下:

-----------------------------------
常数 常数值 说明
-----------------------------------
adLockReadOnly 1 缺省值,Recordset对象以只读方式启动,无法运行AddNew、Update及Delete等方法
adLockPrssimistic 2 当数据源正在更新时,系统会暂时锁住其他用户的动作,以保持数据一致性。
adLockOptimistic 3 当数据源正在更新时,系统并不会锁住其他用户的动作,其他用户可以对数据进行增、删、改的操作。
adLockBatchOptimistic 4 当数据源正在更新时,其他用户必须将CursorLocation属性改为adUdeClientBatch才能对数据进行增、删、改的操作。

=====定义数据库连接的一些常量

Const adOpenForwardOnly = 0 '游标只向前浏览记录,不支持分页、Recordset、BookMark
Const adOpenKeyset = 1 '键集游标,其他用户对记录说做的修改将反映到记录集中,但其他用户增加或删除记录不会反映到记录集中。支持分页、Recordset、BookMark
Const adOpenDynamic = 2 '动态游标功能最强,但耗资源也最多。用户对记录说做的修改,增加或删除记录都将反映到记录集中。支持全功能浏览(ACCESS不支持)。
Const adOpenStatic = 3 '静态游标,只是数据的一个快照,用户对记录说做的修改,增加或删除记录都不会反映到记录集中。支持向前或向后移动

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

Const adCmdText = &H0001
Const adCmdTable = &H0002
红叶哥 2010-04-21
  • 打赏
  • 举报
回复
Do While (Not lRs.EOF)
lRs.Fields("内障率").Value = 123

lRs.MoveNext
Loop
lRs.Update
Fanks 2010-04-21
  • 打赏
  • 举报
回复
楼主你现在的代码与3楼的语句是等效的,无非就是把“123”用变量代替而已,另外对于你报出的错误,是由于你的表内存在重复的记录(所有字段内容都一致)所导致的。
饮水需思源 2010-04-21
  • 打赏
  • 举报
回复
update 后不写where条件就是更新整个表
红叶哥 2010-04-21
  • 打赏
  • 举报
回复
lRs.Open "select * from [Temp]", cN, adOpenStatic, adLockOptimistic
改為:
lRs.Open "select * from [Temp]", cN, adOpenKeyset, adLockOptimistic
还有人用VB6吗 2010-04-21
  • 打赏
  • 举报
回复
当读取第一条记录时,更新了其中的一个字段,然后 执行update 时 跳出,报错
还有人用VB6吗 2010-04-21
  • 打赏
  • 举报
回复
我不是更新一条数据,而是整个表,而且不是固定值,需要计算,否则就像你那么写了
饮水需思源 2010-04-21
  • 打赏
  • 举报
回复
cn.execute " update [temp] set 内障率=123 "
还有人用VB6吗 2010-04-21
  • 打赏
  • 举报
回复


原数据
还有人用VB6吗 2010-04-21
  • 打赏
  • 举报
回复

1,216

社区成员

发帖
与我相关
我的任务
社区描述
VB 数据库(包含打印,安装,报表)
社区管理员
  • 数据库(包含打印,安装,报表)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧