1

我有三个数据库表:

Student{RollNo(primary key), Name etc.}


Book{Id(primary key),NoOfCopiesAvailable etc.}

IssuedBook{RollNo(Foreign Key referencing Student(RollNo)), Id(Foreign Key referencing Book(Id)}

现在,一个学生不能发行超过 5 本书(意味着 RollNo 不能在 IssuedBook 表中出现超过 5 次。对吗?)并且只有在 'NoOfCopiesAvailable'>0 时才能发行一本书。

所以,我写了以下触发器:

CREATE TRIGGER trigger_IssuedBook ON IssuedBook
INSTEAD OF INSERT
AS BEGIN
IF((SELECT NoOfCopiesAvailable FROM Book WHERE Id=(SELECT Id FROM INSERTED))>0 AND (SELECT COUNT(RollNo) FROM StudentBook)<5)
INSERT INTO StudentBook SELECT RollNo,Id FROM INSERTED
ELSE
//Stucked up here. Want to send a message/alert back to application(C#). Don't know how to achieve that.
END

这可以实现吗?如果是,请告诉我,如果可能,请提供编码。或者如果有任何其他方法可以解决这整个事情,那么请分享。我会非常感谢你的帮助。
谢谢你!

注意:使用 C# 编码的 Windows 窗体更新数据库,SQL Server 2008

4

1 回答 1

0

将业务逻辑放在触发器中并不是一个好主意,并且让触发器将特定的错误消息传回给 C# 代码是很困难的。此外,您的触发器没有使用交易,因此学生最终可能会得到超过 5 本书。

我会将 SELECT COUNT 和 INSERT 语句都放在事务中。这可以在 C# 中,也可以在存储过程中。这保证了另一个 SQL 查询在事务成功或回滚之前无法插入记录。

这是一些带有 Linq 的 C# 代码,可帮助您入门。

public static bool CheckoutBook(int bookID, int studentID)
{
    try
    {
        using (var dc = new LibraryDataContext())
        {
            using(var tran = dc.Connection.BeginTransaction())
            {
                var bookCount = dc.StudentBook.Count(a => a.StudentID == studentID);

                if (bookCount < 5)
                {
                    var studentBook = new StudentBook();
                    studentBook.StudentID = studentID;
                    studentBook.BookID = bookID;
                    studentBook.CreateDate = DateTime.Now;
                    dc.StudentBook.InsertOnSubmit(studentBook);

                    dc.SubmitChanges();
                    dc.Transaction.Commit();
                    return true;
                }
            }
        }
    }
    catch (Exception ex)
    {
        //the transaction failed for some reason
    }

    return false;
}
于 2013-10-18T22:16:45.913 回答