2014-12-31 25 views
1

我很难理解如何执行两个表之间的一对多双向强制关系。我有两个表,大致类似的东西:SQL Server:如何在事务结束时执行完整性?

CREATE TABLE Trips 
(
    tripID int IDENTITY(1, 1), 
    starts date NOT NULL, 
    ends date NOT NULL 
); 


CREATE TABLE TripDays 
(
    tripDayID int IDENTITY(1, 1), 
    tripID int NOT NULL, 
    date date NOT NULL, 
    expenses money NOT NULL, 
    foreign key (tripDayID) references Trips (tripID) 
); 

一般来说,我想为旅行中的每一天,从startsends,有第二个表中的条目。为此,我准备了两个将数据插入相关表格的程序,我们称它们为createTripcreateTripDay。为了填补它们,我首先调用第一个参数startsends,然后我使用从第一个过程返回的tripID调用第二个适当的次数。

为了确保始终保持完整性,我在表Trips上创建了一个触发器,在表TripDays缺少相关条目的情况下将事务回滚。不幸的是这个触发器显然不能看到哪些尚未将要制造的第二程序的调用的变化,因为他们尚未提交事务中的包裹插入:

BEGIN TRANSACTION; 

    -creating the trip 
    <- the trigger raises error over violation of the integrity constraints 
    -creating entries in TripDays 

    COMMIT; 

有任何延迟触发器执行直到交易结束的方式?这是一个通常的AFTER INSERT之一。

唯一能解决问题的其他解决方案是在触发器中创建条目,但他们将缺少填充expenses字段所需的信息。如果延迟触发是不可能的,我还会欣赏一些替代解决方案。感谢您的帮助。

+0

为了将来的参考 - 当使用Postgres或Oracle时,您可以推迟检查约束,直到事务提交之前。不幸的是,尽管SQL Server至少从SQL99开始被定义,但它并没有提供这个功能。这可以让循环引用(如强制一对多关系)没有问题。 – lared

回答

0

看起来像你的FK是错误的(或有一个错字)。不应将FK设置为​​TripDays.tripID到Trips.tripId?

你能提供关于你的存储过程的信息吗?看起来Tripdays中的proc应该是Trips的工作,所以不知道它会如何违反FK。

+0

对不起,没有工作的代码,我在旅途中写它,不幸的是我只有一个远程访问服务器。以下是整个代码:https://gist.github.com/anonymous/a5539ded8084522b2fee/ – lared

+0

我明白了。因此,由于您每次只插入一个日期,触发器会针对每个条目触发。 我认为这可能是错误的方法,因为它也不包括更新和删除等内容。所以,如果您更新旅行表来更改日期,您的TripDays将是错误的。 我想你应该制作一个单独的存储过程,用来检查表中是否填满了全部范围。 或者改变你的方式,不要自动填写TripDays表格,只需在费用输入时填写它们,然后在域中进行日期验证。 –

+0

给了它更多的想法,你是对的。虽然我可以以某种方式实施一个像我最初想要的那样工作的解决方案,但它会很尴尬。我想我会用懒惰的解决方案来等待价格进入,而这一切都必须发生。感谢您的时间和建议。 – lared

0

伯爵是正确的约错字

从第二SP移动你的代码到旅程的更新/ INSERT触发器应该解决您的问题。

相关问题