Office中国论坛/Access中国论坛

标题: 我的触发器出错了,错在哪? [打印本页]

作者: 李寻欢    时间: 2004-2-14 05:56
标题: 我的触发器出错了,错在哪?
ALTER TRIGGER tbl材料公共信息_Trigger
ON dbo.tbl材料公共信息
after INSERT
AS
declare @ckcl table
(ckh char(5) not null,
clh char(8) null
)

/*这句出错,把tbl仓库表中的所有仓库编号插入临时表@ckcl*/
insert into @ckcl(ckh)
     select 仓库编号 FROM tbl仓库

/*更新临时表@ckcl中的clh字段为刚插入的材料编号*/
update @ckcl set clh=(select 材料编号 from inserted)

/*把临时表@ckcl中的所有信息插入tbl仓库材料信息表的对应字段中*/
insert into dbo.tbl仓库材料信息(仓库编号,材料编号)
     select * from @ckcl
作者: 李寻欢    时间: 2004-2-14 17:57
标题: 这是sql server的备份文件,还原回sql server中就可以了
顶一下。
[attach]3483[/attach]
作者: 李寻欢    时间: 2004-2-14 19:16
标题: 用游标实现了上面那个触发器
ALTER TRIGGER tigInsertCKCL
ON dbo.tbl材料公共信息
FOR INSERT
AS
declare @ckh char(5)
declare @clh char(8)
declare ck_cursor cursor
        local
        fast_forward
        for select 仓库编号 from tbl仓库
select @clh=材料编号 from inserted

但上面的为何不行呢?谁能告诉我?

open ck_cursor

fetch next from ck_cursor into @ckh

while (@@fetch_status=0)
begin
        insert into tbl仓库材料信息(仓库编号,材料编号)
        values(@ckh,@clh)
        fetch next from ck_cursor into @ckh
end

close ck_cursor
deallocate ck_cursor
作者: zhuyiwen    时间: 2004-2-14 22:24
T-SQL联机帮助:

table 变量的行为类似于局部变量,有明确定义的作用域。该作用域为声明该变量的函数、存储过程或批处理。
在其作用域内,table 变量可像常规表那样使用。该变量可应用于 SELECT、INSERT、UPDATE 和 DELETE 语句中用到表或表的表达式的地方。但是,table 不能用在下列语句中:

INSERT INTO table_variable EXEC 存储过程。

SELECT select_list INTO table_variable 语句。

在定义 table 变量的函数、存储过程或批处理结束时,自动清除 table 变量。

=======================================
可以这样(示例):

   DECLARE @reports TABLE (empid nchar(5) primary key,
      empname nvarchar(50) NOT NULL,
      mgrid nchar(5),
      title nvarchar(30),
      processed tinyint default 0)
-- initialize @Reports with direct reports of the given employee
   INSERT @reports
   SELECT empid, empname, mgrid, title, 0
   FROM employees
   WHERE empid = @InEmpId



作者: 李寻欢    时间: 2004-2-16 03:50
我今天拿到学校的机房去用,竟然没错,好奇怪。
有条件的朋友请帮我测试一下,下载上面的文件,还原回SQL server中,然后在“tbl材料公共信息”表中输入一条记录,看是否会出错。
我在三台机器上运行都出错,但今天在第四台机器上运行却没错。
作者: zhuyiwen    时间: 2004-2-16 04:29
以下是引用李寻欢在2004-2-15 19:49:34的发言:
我今天拿到学校的机房去用,竟然没错,好奇怪。
有条件的朋友请帮我测试一下,下载上面的文件,还原回SQL server中,然后在“tbl材料公共信息”表中输入一条记录,看是否会出错。
我在三台机器上运行都出错,但今天在第四台机器上运行却没错。


在我这里也没有出错.

环境:Win XP + MSDE2000ReleaseSP3a

在tbl材料公共信息表中添加3条记录,如下:
        12              1         1         sdfw        34        gjj        45        4
        22              1         1         wwe                                2
        33              1         1         fgj        f        g        j        1
自动在tbl仓库材料信息中增加了6条记录,如下:
        zx001        12                                                             
        zx001        22                                                             
        zx001        33                                                             
        ZX002        12                                                             
        ZX002        22                                                             
        ZX002        33                                                             

不知对不对.
作者: 李寻欢    时间: 2004-2-16 05:24
结果是对的,那可能是我的系统的问题,我再找找原因,谢谢。
作者: HG    时间: 2004-2-16 19:32
这是因为你是否打过SQL SP2或更高版本SP的问题 !
严格说来,Insert into Table 语句中的Table须求的是指定一个表名,而非变量!
作者: 李寻欢    时间: 2004-2-16 20:34
我的SQL SERVER2000是默认安装的,没打任何补丁。
刚刚下载了SP3的补丁并安装,装完之后原来错的那个触发器可以用了,不用使用游标了。
开心:)
作者: 李寻欢    时间: 2004-2-16 20:49
标题: 但在Access中还是不行
刚刚打完SQL的sp3被丁,在SQL SERVER里直接输入数据,触发器可以正常运行了
回到Access里,在表中输入,跟以前一样弹出以下对话框:

[attach]3501[/attach]

是否一定要用access2003呢?
作者: 李寻欢    时间: 2004-2-16 20:56
在Access中用语句插入记录也没问题,触发器正常运行
docmd.RunSQL "insert into tbl材料公共信息(材料编号) VALUES('01020002') "

只是在表中直接输入记录会出错。


作者: zhengjialon    时间: 2004-2-16 21:49
试试ACCESS打补丁看。
记得好像有这种情况,在SQL表中好像直接输数据时会出错,很长时间了,现在忘的差不多了。
作者: 李寻欢    时间: 2004-2-17 00:52
accessxp的补丁哪里有下载?安装后是不是要重新激活?
作者: 阿罗    时间: 2004-2-17 01:39
我以前也碰到过类似的问题,我找到那些代码,但是只找到自己写的唯一一句注释:

--must insert one by one

我的存储过程是这样的
CREATE TRIGGER newEmp ON dbo.employee
FOR INSERT AS   /*添加新员工的触发器*/
DECLARE @depID int    /*depID: 部门编号*/
SET @depID= (SELECT depID FROM inserted )
SET NOCOUNT ON
IF @depID <>0     /*如果新员工已经被指定了一个部门,那么将该部门默认权限指定给他*/
INSERT INTO empRights  /*empRights: 员工权限表*/
              SELECT @@identity, rID, needCensor, rights, censorDepID, censorEmpID, 0
         FROM depRights WHERE depRights.depID = @depID
SET NOCOUNT OFF
--must insert one by one  (除了这句,所有的注释都是现在加的)

我记得我的问题来自SET @depID= (SELECT depID FROM inserted ),因为同时提交多条记录后,即使对于不同的depID,SET @depID=select...这条语句, 只给出select结果的第一个值。

我看了你写的两个存储过程后, 第一个:

update @ckcl set clh=(select 材料编号 from inserted)
同我上面这个有相似地方。

第二个,用cursor:
for select 仓库编号 from tbl仓库 select @clh=材料编号 from inserted

就不存在上述这个问题了。

我想,问题的根源在于,触发器动作后,无论你一次提交了多少条记录,你在触发器中设置的变量,不要指望它还能按照你的要求根据每条提交的记录改变。


作者: 阿罗    时间: 2004-2-17 01:41
呵呵,版主聚会帖。
作者: 阿罗    时间: 2004-2-17 06:36
其他可能的原因,请看
http://www.office-cn.net/bbs/dispbbs.asp?boardID=5&ID=9550
作者: HG    时间: 2004-2-17 16:56
在打过SP2后,最好的解决方法是用conn.execute(sql)来执行!
不要再去找什么ACCESSXP的补丁啦!好麻烦!
作者: lwwvb    时间: 2004-4-18 21:08
嘿嘿,我不懂SQL 2000和ADP,但我用过VB+ADO+第三方控件,你的错误的对话框,很可能是因为数据集没有主键造成的。也就是说,表和数据集中一定非要有一个主键不可。插入数据是非要有主键的(这个我也不知道为什么?)

但我用VB+ADO+第三方控件的时间太短了,实在是对这些理解不多。

作者: lwwvb    时间: 2004-4-18 21:10
而且还有一点,没有主键造成的错误是很奇怪的,有时它能正常工作,但有时它就不能正常工作,最初,我还以为系统出问题了,也是急得要死。
作者: 土豆    时间: 2004-4-19 21:45
关于ACCESS2000与SQL2000的兼容问题:因为OFFICE2000发布比SQL2000早,所以存在一些兼容问题。

解决办法是客户机安装SQL客户端实用工具以及OFFICE-SR1




欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) Powered by Discuz! X3.3