.Net SqlDataAdapter 和 SQL Server 触发器

3

我在SQL Server中使用触发器,当在SQL Server Management Studio的查询窗口中执行查询时,它按要求工作。该触发器的目的是从一个表中获取最新值(其中一个ID对应插入的ID),并将此值添加到插入的行中。

我还在C#中使用DataAdapter与具有触发器的同一数据库进行交互。当我使用MyAdapter.update(MyDataTable)向分配了触发器的表中插入新值时,触发器不会执行。

我已经做了很多谷歌搜索,但似乎没有其他人遇到这个问题,所以我认为我可能漏掉了一些基本的东西。我还是.NET中的数据库交互新手。数据适配器可以正常工作(即根据需要插入和更新),除了不触发触发器之外。

以下是我的C#代码和触发器的一些摘录。

CREATE TRIGGER getLatestCap 
ON  TestIDTable 
AFTER insert
AS 
BEGIN
    SET NOCOUNT ON;

    DECLARE @BID INT;
    DECLARE @Date Date;

    SET @BID = (SELECT BattID FROM inserted);
    SET @Date = (SELECT Test_Date FROM inserted);

    SELECT M_Cap, Cap_Date
    INTO #tempTable
    FROM CapDataTable
    WHERE BattID = @BID;

    -- Set the Test_Cap entry in TestIDTable to that capacity. 
    UPDATE TestIDTable 
    SET Test_Cap = (SELECT M_Cap
                    FROM #tempTable
                    WHERE Cap_Date = (SELECT max(Cap_Date)
                                      FROM #tempTable))
    WHERE BattID = @BID AND Test_Date = @Date;
END
GO

private void Setup()
{
        try
        {
            string BattSelect = "SELECT * FROM " + tbl;
            dt = new DataTable();
            Adpt = new SqlDataAdapter(BattSelect, ConnectionStr);
            builder = new SqlCommandBuilder(Adpt);
            Adpt.Fill(dt);
        }
        catch (Exception e)
        {
            MessageBox.Show("While Connecting to "+tbl+": " + e.ToString());
        }
    }

    private void UpdateDB()
    {
        try
        {
            Adpt.InsertCommand = builder.GetInsertCommand();
            Adpt.UpdateCommand = builder.GetUpdateCommand();
            Adpt.Update(dt);
        }
        catch (Exception e)
        {
            MessageBox.Show("While Updating " + tbl + ": " + e.ToString());
        }
    }

问题概要:触发器在SQL Server中有效,但使用数据适配器时不会触发(也没有报错)。
感谢您的时间和帮助!
马文

2
提示:inserteddeleted是表格,因此它们可以表示集合操作的结果。在设计触发器时,假设它们总是包含一行数据通常是一个不好的计划。如果您绝对确定永远不会有多于一行的情况,请添加一个检查行数的条件,并使用RaIsError来明确告知那些随后尝试执行不可接受语句的人。 (if (select Count(*) from inserted) > 1 RaIsError('FooTable_Insert: No more than one row may be processed.', 25, 42) with log) - HABO
谢谢你的回答。在对触发器中的单次插入问题进行了一些研究后,我非常确定重写我的触发器以处理多个插入将解决我的问题。我会尽快再次发布结果。 - user2502832
2个回答

2

根据HABO的提示(原帖下),我修改了触发器以适用于多个插入行。这解决了我的问题。以下是新的触发器代码:

 CREATE TRIGGER getLatestCap
    ON TestIDTable
    AFTER insert
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE TestIDTable 
    set Test_Cap = M_Cap
    FROM 
        (SELECT C.BattID, Test_Date, M_Cap
        FROM 
            (SELECT t.BattID, t.M_Cap, t.Cap_Date 
            FROM CapDataTable t
            INNER JOIN(
                SELECT BattID, max(Cap_Date) as Latest
                FROM CapDataTable
                GROUP BY BattID
            ) tm on t.BattID = tm.BattID and t.Cap_Date = tm.Latest)

         C INNER JOIN inserted I
            on C.BattID = I.BattID) as t1
        INNER JOIN TestIDTable as t2
        on  t1.BattID = t2.BattID AND t1.Test_Date = t2.Test_Date
END
GO

感谢您的帮助!

1
您在执行INSERT操作后触发了触发器。使用SQLDataAdapter时,您正在执行UPDATE操作。这些是两种非常不同的事务。
尝试将您的触发器设置为ON UPDATE。那应该就可以解决问题了。

感谢您的回答。1. 根据我的理解,adapter.update() 可以根据数据表中所做的更改执行任何 INSERT、DELETE 或 UPDATE 操作。这不是这种情况吗?2. 我尝试使用 ON UPDATE 而不是 ON INSERT,但这并没有解决问题。 - user2502832
是的,没错,我没有看到你也添加了一个插入命令。 - romatthe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接