我在该表上使用 INSERT Trigger 。一旦执行了触发器(如果条件满足则更新表),这就是问题所在。
int records = sc.ExecuteNonQuery(); // works ok if trigger does not update the record
如果我在存储过程本身中留下SET NOCOUNT ON;
,上面的代码总是ruturns -1。如果我删除它,我得到正确的结果,但如果触发器确实更新记录,那么错误的结果。我有时会得到10或不同的数字。我的触发器看起来像这样
UPDATE students
SET status = 'Inactive'
FROM Inserted i
INNER JOIN students T2
ON i.sname = T2.sname
AND i.id <> t2.id
这意味着它可以返回多个记录(特别是在测试用例中)。谁能告诉我什么是治疗方法?如果能解决问题或任何更好的方法,我愿意使用函数。
由于
CREATE PROCEDURE sp_InsertSudent
-- Add the parameters for the stored procedure here
@student_name varchar(25) = null,
@status varchar(20) = null,
@renew varchar(15) = null,
@edate datetime = null
AS
BEGIN
--SET NOCOUNT ON;
insert into students VALUES(@student_name,@status,@renew,@edate)
END
GO
注意:我正在查找错误,因为这些字段是从Excel中选取的。如果任何字段格式错误或为空,则插入SP将产生错误。我必须将错误传达给用户。
所以整个问题都在SP中。如果我删除它,一切正常。这是我的实际SP
UPDATE CustomerTbl
SET [Account Status] = 'Inactive',
[End Date] = DateAdd(day,-1,[Supplier End Date]),
[EnrollmentStatus] = 'Waiting'
WHERE OET.[Account No] = (SELECT [Account No] FROM CustomerTbl WHERE id = @@identity)
AND id <> @@identity
逻辑与上述相同,但说明不同。 ExecuteNonQuery会触发此触发器的结果,而不是实际存储过程的结果,那么他的治疗方法是什么?可以某种方式抑制其输出。
答案 0 :(得分:0)
也许我不理解这个问题,但是如果您的目标是跟踪插入的行数,那么您将保留一次调用存储过程的次数(假设你的sproc一次插入一行。
或者,如果您尝试维护受影响的记录总数(通过插入和更新),则可以将触发器中的逻辑合并到您的sproc中。受insert语句(始终为1)和update语句(更新完成后@@ rowcount)影响的行...然后您可以将该值返回给调用者。
更新: 当然,如果有错误,请返回0。如果使用SQL2005(或更高版本),请使用TRY / CATCH机制。
答案 1 :(得分:0)
我会在proc中添加Try Catch块,如果成功则返回1,如果不成功则返回0。
我还会通过仅处理活动状态并满足其他条件的状态来调整触发器以提高效率。
UPDATE students
SET status = 'Inactive'
FROM Inserted i
INNER JOIN students T2
ON i.sname = T2.sname
AND i.id <> t2.id
AND status <> 'inactive'
当您只需要更新一个活动行时,这可以使您免于更新1000行。
答案 2 :(得分:0)
我自己的答案(尚未完成)。 According to MSDN documentation用于ExecuteNonQuery
当插入或更新的表上存在触发器时,返回 value包括插入或者受影响的行数 更新操作和受触发器影响的行数 触发器。
这意味着我需要修改触发器本身以适应逻辑,或者甚至通过调用触发器时证明记录成功的事实。这意味着如果我得到大于0的任何东西,那应该被认为是成功的。虽然不是很扎实的逻辑,但它会起作用。必须为此注释SET COUNT ON。
答案 3 :(得分:0)
添加一个额外的列,存储的proc不会填充(留空) 然后,当触发器运行时,只需将Null值更新为非null值,并使用Update中的RowCount来确定更新的行数。