环境如下:
windows XP , delphi 7.0 , SQL Server 2005.
现利用ADO通过ADOQuery对js(角色)表做插入操作,当js表无触发器时保存一切正常,当有下列insert触发器时保存报错CREATE TRIGGER [js_insert] ON [dbo].[qx_js]
FOR INSERT
AS
declare @c_jsdm char(3)
declare C_js1 CURSOR for SELECT DISTINCT jsdm FROM inserted
open c_js1
fetch c_js1 into @c_jsdm
while @@fetch_status = 0
begin
INSERT INTO qx_jsqx (jsdm , jsqxdm, qxbz) SELECT @c_jsdm , qxdm , '0' FROM qx_qx
fetch c_js1 into @c_jsdm
end
close c_js1
deallocate c_js1报错信息如下“键列信息不足或下正确。更新影响到多行。”如删除INSERT INTO qx_jsqx (jsdm , jsqxdm, qxbz) SELECT @c_jsdm , qxdm , '0' FROM qx_qx这行,则不报错。请指导。(注:触发器代码正确)
windows XP , delphi 7.0 , SQL Server 2005.
现利用ADO通过ADOQuery对js(角色)表做插入操作,当js表无触发器时保存一切正常,当有下列insert触发器时保存报错CREATE TRIGGER [js_insert] ON [dbo].[qx_js]
FOR INSERT
AS
declare @c_jsdm char(3)
declare C_js1 CURSOR for SELECT DISTINCT jsdm FROM inserted
open c_js1
fetch c_js1 into @c_jsdm
while @@fetch_status = 0
begin
INSERT INTO qx_jsqx (jsdm , jsqxdm, qxbz) SELECT @c_jsdm , qxdm , '0' FROM qx_qx
fetch c_js1 into @c_jsdm
end
close c_js1
deallocate c_js1报错信息如下“键列信息不足或下正确。更新影响到多行。”如删除INSERT INTO qx_jsqx (jsdm , jsqxdm, qxbz) SELECT @c_jsdm , qxdm , '0' FROM qx_qx这行,则不报错。请指导。(注:触发器代码正确)
插入或者update的时候,因为你直接操作的的时候遇到你要操作的那行数据之外一模一样数据列,系统区分不了你要操作那一行。
用一个主键约束
to starluck :
貼出ADO執行的QUERY那部分代碼。
代码就是,ADOQuery.post;
触发器中只改变了表qx_jsqx的内容,没有改变qx_js表内容,而ADOQUERY的sql语句是select * from qx_js。
SELECT @c_jsdm = jsdm FROM inserted
INSERT INTO qx_jsqx (jsdm , jsqxdm, qxbz) SELECT @c_jsdm , qxdm , '0' FROM qx_qx
如果一次修改qx_js中多条记录,你的方法就不行了。所以必须用游标。
本身在Trigger中处理游标就会使数据库压力比较大!
我的思路是先把Trigger的代码与处理思路规范一下,再处理你描述的问题,否则这段代码以后肯定要修改,只处理眼前的错误无意义!
INSERTED逻辑表是一个集合,你可以使用某种关系与逻辑表进行关联,从而就插入了表集!SET NOCOUNT ON
IF Exists(SELECT 1 FROM INSERTED)
INSERT INTO qx_jsqx(jsdm , jsqxdm, qxbz)
SELECT I.jsdm ,Q.qxdm ,0
FROM INSERTED I
INNER JOIN qx_qx Q
ON I.xx=Q.xx
GROUP BY I.jsdm
SET NOCOUNT OFF
CREATE TRIGGER [js_insert] ON [dbo].[qx_js]
FOR INSERT
AS
declare @c_jsdm char(3)
declare C_js1 CURSOR for SELECT DISTINCT jsdm FROM inserted
open c_js1
fetch c_js1 into @c_jsdm
while @@fetch_status = 0
begin
INSERT INTO qx_jsqx (jsdm , jsqxdm, qxbz) SELECT @c_jsdm , qxdm , '0' FROM qx_qx
fetch c_js1 into @c_jsdm
end
close c_js1
deallocate c_js1
直接在SQL SERVER存储过程中执行看有错吗?
已有主键.
如果一次修改qx_js中多条记录,不用游标就无法取得多个修改后jsdm字段的值。
首先感谢.
SELECT @c_jsdm , qxdm , '0' FROM qx_qx 返回的是多条记录,语法没有错,为什么用ADO连接报错,用BDE连接就正确呢。
主键肯定没有重复.
不介存储过程中执行不出错,用BDE连接也正确,只是用ADO连接报错.
插入的绝对没有记录重复。因为我有BDE连接就不报错,而且直接用sql语句也正确。
ADOQUERY好像没有什么post提交数据的吧,你在程序中debug看看是不是在ADOQuery.post时报错的。
的可能性都說了,你再調試一下,要不貼出全部代碼
首先,谢谢。
ADOQUERY一定有post提交数据。因为我不改delphi中代码,禁止表的触发器,就可正确执行,不报错。
to kye_jufei :
感谢。
查詢分析器裡執行檢查sql語句不报错,正确。
GO
/****** Object: StoredProcedure [dbo].[SP_WKO_SCHEDULE] Script Date: 01/14/2009 10:03:23 ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_WKO_SCHEDULE] AS
delete from WKO_SCHEDULE where dateadd(dd,60,ImportDate)<=getdate()
delete from WKO_SCHEDULE where (WKO_XB is null)and(WKO_BC is null)and(WKO_HS is null) if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ttt]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[ttt] select * into ttt
from
(
select *,case IsSMT when 1 then NHR*WKO_QTY else NHR*WKO_QTY/BZRS end as womenyaode
from
(
select *,case isnull(TT,0) when 0 then WKO_TIMES/WKO_QTY else TT end as NHR,case isnull(RS,0) when 0 then 25 else RS end as BZRS
from
(
select *,
case WKO_TIMES when WKO_TIMES then (select NewHR/1000 from PRO_QUANTITY a where PN=WKO_ITEMNO and GX=WKO_GX and CBZX=WKO_CBZX) end as TT,
(select BZRS from PRO_QUANTITY where PN=WKO_ITEMNO and GX=WKO_GX and CBZX=WKO_CBZX) AS RS,case when WKO_CBZX in (select distinct CBZX from RES_XB where DomainType=1) then 1 else 0 end as IsSMT
from TMP_WKO_ORDER
) f where WKO_TYPE<>'WO' and WKO_TYPE<>'WW' and WKO_STATUS<91
)_f
)_ff where WKO_TIMES is not null
DECLARE @WKO_STATUS NVARCHAR(100),@WKO_ITEMNO NVARCHAR(100),@WKO_TYPE NVARCHAR(100),@WKO_DESC NVARCHAR(100),@WKO_BZRS NVARCHAR(100),@WKO_PLANER NVARCHAR(100),@WKO_QTY INT,@WKO_CBZX NVARCHAR(100),@WKO_GX INT ,@WKO_TIMES FLOAT,@WKO_ODATE NVARCHAR(100),@WKO_HS FLOAT ,@WKO_MOVECL FLOAT,@STATUS int
DECLARE @WKO_ORDERNO NVARCHAR(100)
declare Searchcursor cursor for select WKO_STATUS,WKO_ITEMNO,WKO_TYPE,WKO_DESC,RS,WKO_PLANNER,WKO_QTY,WKO_CBZX,WKO_GX,NHR,WKO_ODATE,womenyaode,WKO_ORDERNO from ttt
open Searchcursor
fetch next from Searchcursor into @WKO_STATUS,@WKO_ITEMNO,@WKO_TYPE,@WKO_DESC,@WKO_BZRS,@WKO_PLANER,@WKO_QTY,@WKO_CBZX,@WKO_GX,@WKO_TIMES,@WKO_ODATE,@WKO_HS,@WKO_ORDERNO
while(@@fetch_status=0)
begin
--print('前,WO:'+@WKO_ORDERNO+',GX:'+convert(nvarchar(20),@WKO_GX)+',CBZX:'+@WKO_CBZX)
if not exists(select * from WKO_BACK_SCHEDULE where WKO_ORDERNO=@WKO_ORDERNO and WKO_GX=@WKO_GX)
begin
--print('后,WO:'+@WKO_ORDERNO+',GX:'+convert(nvarchar(20),@WKO_GX)+',CBZX:'+@WKO_CBZX)
if not exists(select * from WKO_SCHEDULE where WKO_ORDERNO=@WKO_ORDERNO and WKO_GX=@WKO_GX and WKO_CBZX=@WKO_CBZX)
begin
EXEC SP_WKO_JPJJCL @WKO_ITEMNO,@WKO_GX,@WKO_CBZX,@Result=@WKO_MOVECL OUTPUT
INSERT INTO WKO_SCHEDULE(WKO_STATUS,WKO_ITEMNO,WKO_TYPE,WKO_DESC,WKO_BZRS,WKO_PLANER,WKO_QTY,WKO_CBZX,WKO_GX,WKO_TIMES,WKO_ODATE,WKO_HS,WKO_ORDERNO,WKO_MOVECL)
VALUES(@WKO_STATUS,@WKO_ITEMNO,@WKO_TYPE,@WKO_DESC,@WKO_BZRS,@WKO_PLANER,@WKO_QTY,@WKO_CBZX,@WKO_GX,@WKO_TIMES,@WKO_ODATE,@WKO_HS,@WKO_ORDERNO,@WKO_MOVECL)
end
end else
begin
update WKO_SCHEDULE set WKO_STATUS=@WKO_STATUS where WKO_ORDERNO=@WKO_ORDERNO and WKO_GX=@WKO_GX and WKO_CBZX=@WKO_CBZX
end
fetch next from Searchcursor into @WKO_STATUS,@WKO_ITEMNO,@WKO_TYPE,@WKO_DESC,@WKO_BZRS,@WKO_PLANER,@WKO_QTY,@WKO_CBZX,@WKO_GX,@WKO_TIMES,@WKO_ODATE,@WKO_HS,@WKO_ORDERNO
end
close Searchcursor
deallocate Searchcursor
drop table [dbo].[ttt]
有主键。