触发器引起“键列信息不足或不正确。更新影响到多行”

gallardo 2006-12-03 10:38:16
有很多类似错误的帖子,但回答都是说没有主键或者有重复数据,但我的都是有主键的而且没有重复数据。但是有一个触发器,数据结构是这样的:

表A
用户名 ...
admin ...

表B
模块号 模块名
1 库存管理

表C
PID 用户名 模块号 权限
1 admin 1 ...

我的想法是当增加一个用户时自动根据添加的用户名和所有模块号初始化此用户的所有模块的权限,所以建立了一个触发器,在企业管理器和查询分析器中一切正常,但是在BCB中用ADO操作却出现“键列信息不足或不正确。更新影响到多行”的错误。

有一点要说明的是虽然程序中出现上述错误,但是数据库中的数据是已经正确添加了的,但是如果继续操作用户表数据就会乱了,除非Requery或者重新打开用户表.
...全文
316 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
madyak 2006-12-06
  • 打赏
  • 举报
回复
主要是客户端得到的返回系统信息混乱所致。
gallardo 2006-12-06
  • 打赏
  • 举报
回复
多谢,发现这个对另外一个删除的触发器也有效,错误是“无法为更新定位行。一些值可能已在最后一次读取后已更改”,这个触发器类似于主从表的级联删除,但是明细表中又允许有自己的键值,当明细表不存在与主表相对应的键值时,删除主表数据就会有这个错误,是不是这样?
madyak 2006-12-06
  • 打赏
  • 举报
回复
没有影响,触发器执行完后,会自动恢复成原来的设置。
gallardo 2006-12-06
  • 打赏
  • 举报
回复
楼上的方法可以,但是要不要在最后加上set nocount off还原默认设置?还有这会对其他地方有没有影响?
madyak 2006-12-06
  • 打赏
  • 举报
回复
在触发器的开始加一句话
create trigger TR_Users on Users
for insert as
Set NoCount on
....
78hgdong 2006-12-05
  • 打赏
  • 举报
回复
你单独每个字段更新看看,之后再一个一个增加,用排除法查错...
gallardo 2006-12-05
  • 打赏
  • 举报
回复
这也太牵强了吧,在ODBC驱动和查询分析器里都可以,而且我的触发器增加了数据的那个表有一个自动增长的ID,其他两个表虽然没有,但是都有唯一值的主键,我开始怀疑ADO的可靠性,连MSDN都没有说明这种问题。
gallardo 2006-12-05
  • 打赏
  • 举报
回复
来个最简单的例子:
Table1(id为自增量主键)
id uname

Table2(id为自增量主键)
id title

Table1上的触发器
CREATE TRIGGER [tr_table1] ON Table1
FOR INSERT AS
Insert into table2(title) select 'title1' union select 'title2' union select 'title3'

在Table1加入一行后会在Table2插入三行'title',在企业管理器和查询分析器中都通过。
在BCB6 Update4,ADO2.8中插入Table1时会有错误“键列信息不足或不正确。更新影响到多行”
但实际上数据已经正确加入,要用事实说话。
gallardo 2006-12-05
  • 打赏
  • 举报
回复
既然我的代码有问题,那么怎么解释用ODBC驱动时又正常呢?这可不是第一次,你既然那么肯定,那你可以试一试
XLYT 2006-12-05
  • 打赏
  • 举报
回复
不要怀疑ADO,99.99%的问题都出在自己身上,仔细检查你的代码,也许问题并不在这条语句上.
cqbonny 2006-12-04
  • 打赏
  • 举报
回复
把你的表另外添加一个主键,定义为自动增长的就应该可以了
XLYT 2006-12-04
  • 打赏
  • 举报
回复
检查一下各表的外键是否产生了冲突.
gallardo 2006-12-03
  • 打赏
  • 举报
回复
还有个奇怪现象,如果表B中只有一条数据就不会出错,超过1条就出错。
gallardo 2006-12-03
  • 打赏
  • 举报
回复
精简了一下,去掉了从Users中取数据,改成:
create trigger TR_Users on Users
for insert as
insert into UserPmt
select a.UserID,b.ModuleID,0,0,0,0 from inserted a,Modules b

不过还是会有错误。
gallardo 2006-12-03
  • 打赏
  • 举报
回复
To楼上:
ADO的连接是可以选的。

这是我的触发器代码,Users是表A,Modules是表B,UserPmt是表C,加用户时增加所有模块编号和增加的用户编号到UserPmt中,看了上面的代码好像还可以精简一下
create trigger TR_Users on Users
for insert as
insert into UserPmt
select a.UserID,b.ModuleID,0,0,0,0 from Users a,Modules b,inserted c where a.UserID=c.UserID
老冯 2006-12-03
  • 打赏
  • 举报
回复
ADOConnection的Driver也是OLE DB Provider for SQL Server
老冯 2006-12-03
  • 打赏
  • 举报
回复
CREATE TRIGGER [TRIGGER_InsertUser] ON [dbo].[TWangs_UserInfo]
FOR INSERT
AS
Insert Into TWangs_UserPowerInfo Select Inserted.FUserID, FUsed=1, TWangs_PowerInfo.* FROM Inserted, TWangs_PowerInfo

前台DELPHI的新增用户也是用的ADO
老冯 2006-12-03
  • 打赏
  • 举报
回复
我把我的应用系统和你类似的触发器代码帖出来,你看看(前台应用是DELPHI)

gallardo 2006-12-03
  • 打赏
  • 举报
回复
没人知道?
还有个现象,如果用OLE DB Provider for ODBC Drivers则不会有问题
如果用OLE DB Provider for SQL Server驱动就会有问题

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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