- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
批处理可以有多个 Bill,而 Bill 可以有多个 BillLine。我在它们之间有 ON DELETE CASCADE FK,这样如果你删除一个 Batch,相关的 Bill 和 BillLine 记录也会被删除。如果删除 Bill,相关的 BillLines 会被删除,但 Batch 记录不受影响。现在,如果一个或多个关联的 BillLine 记录存在特定数据条件,我需要防止删除 Bill。
表 Bill 显然需要一个 INSTEAD OF DELETE 触发器。 BillLine.BillId 有一个 ON DELETE CASCADE FK 引用 Bill.BillId。我需要改为 FK ON DELETE NO ACTION 是有道理的,因为 INSTEAD OF DELETE 触发器有效地替换了 CASCADE 功能。当我删除 Bill 时,INSTEAD OF DELETE 将删除关联的 BillLine 记录或根据某些数据条件引发异常。到目前为止,还不错。
但是,因为 Bill.BatchId 有一个 ON DELETE CASCADE FK 引用 Batch.BatchId,SQL Server 不允许我创建触发器。这个我不明白。为什么我必须在 Batch 上构建一个 INSTEAD OF DELETE 触发器,因为我在 Bill 上有一个触发器?
下面创建表和键的代码(省略了所有无关的列和键)是现在的样子,没有 ON DELETE CASCADE 子句。问题是,为什么 FK_Bill_Batch_BatchId 不能有那个子句,而不是我必须创建一个额外的 INSTEAD OF DELETE 触发器?
CREATE TABLE [Batch](
[BatchId] [bigint] NOT NULL,
CONSTRAINT [PK_Batch_BatchId] PRIMARY KEY CLUSTERED
(
[BatchId] ASC
)
)
CREATE TABLE [Bill](
[BillId] [bigint] NOT NULL,
[BatchId] [bigint] NOT NULL,
[ReversesBillId] [bigint] NULL,
CONSTRAINT [PK_Bill_BillId] PRIMARY KEY CLUSTERED
(
[BillId] ASC
)
)
ALTER TABLE [Bill] WITH CHECK ADD CONSTRAINT [FK_Bill_Batch_BatchId] FOREIGN KEY([BatchId])
REFERENCES [Batch] ([BatchId])
ALTER TABLE [Bill] WITH NOCHECK ADD CONSTRAINT [FK_Bill_ReversesBillId] FOREIGN KEY([ReversesBillId])
REFERENCES [Bill] ([BillId])
CREATE TABLE [BillLine](
[BillLineId] [bigint] NOT NULL,
[BillId] [bigint] NOT NULL,
[ReversedByBillLineId] [bigint] NULL,
CONSTRAINT [PK_BillLine_BillLineId] PRIMARY KEY CLUSTERED
(
[BillLineId] ASC
)
)
ALTER TABLE [BillLine] WITH CHECK ADD CONSTRAINT [FK_BillLine_Bill_BillId] FOREIGN KEY([BillId])
REFERENCES [Bill] ([BillId])
ALTER TABLE [BillLine] WITH CHECK ADD CONSTRAINT [FK_BillLine_ReversedByBillLineId] FOREIGN KEY([ReversedByBillLineId])
REFERENCES [BillLine] ([BillLineId])
GO
CREATE TRIGGER [Bill_Delete]
ON [Bill]
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON
DECLARE @BillId UNIQUEIDENTIFIER
DECLARE myCursor CURSOR LOCAL FORWARD_ONLY
FOR SELECT b.[BillId]
FROM deleted b
JOIN [Batch] bt on b.[BatchId] = bt.[BatchId]
OPEN myCursor
FETCH NEXT FROM myCursor INTO @BillId
WHILE @@FETCH_STATUS = 0
BEGIN
-- Delete BillLine records reversed by another BillLine in the same Bill
DELETE FROM [BillLine]
WHERE [BillId] = @BillId
AND [ReversedByBillLineId] IN
(SELECT bl.[BillLineId]
FROM [BillLine] bl
WHERE bl.BillId = @BillId
);
-- Delete all remaining BillLine records for the Bill
-- If the BillLine is reversed by a BillLine in a different Bill, the FK will raise an exception.
-- That is the desired behavior.
DELETE FROM [BillLine]
WHERE [BillId] = @BillId;
-- Delete the Bill
DELETE FROM [Bill]
WHERE [BillId] = @BillId;
FETCH NEXT FROM myCursor INTO @BillId
END
END
GO
CREATE TRIGGER [Batch_Delete]
ON [Batch]
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON
DECLARE @BatchId UNIQUEIDENTIFIER
DECLARE myCursor CURSOR LOCAL FORWARD_ONLY
FOR SELECT [BatchId]
FROM deleted
OPEN myCursor
FETCH NEXT FROM myCursor INTO @BatchId
WHILE @@FETCH_STATUS = 0
BEGIN
-- Delete all Bill records for the Batch.
-- Another INSTEAD OF DELETE trigger on Bill will attempt to delete the associated BillLine records in the correct order.
-- If the BillLine is reversed by a BillLine in a different Bill, FK_BillLine_ReversedByBillLineId will raise an exception.
-- That is the desired behavior.
DELETE FROM [Bill]
WHERE [BatchId] = @BatchId;
FETCH NEXT FROM myCursor INTO @BatchId
END
END
如果您尝试将 Batch_Delete 触发器替换为 ON DELETE CASCADE:
DROP TRIGGER [Batch_Delete]
ALTER TABLE [Bill] DROP CONSTRAINT [FK_Bill_Batch_BatchId];
ALTER TABLE [Bill] WITH CHECK ADD CONSTRAINT [FK_Bill_Batch_BatchId] FOREIGN KEY([BatchId])
REFERENCES [Batch] ([BatchId]) ON DELETE CASCADE;
你会得到这个:
Msg 1787, Level 16, State 0, Line 2
Cannot define foreign key constraint 'FK_Bill_Batch_BatchId' with cascaded DELETE or UPDATE on table 'Bill' because the table has an INSTEAD OF DELETE or UPDATE TRIGGER defined on it.
Msg 1750, Level 16, State 0, Line 2
Could not create constraint. See previous errors.
我不明白为什么这个方向上的 ON DELETE CASCADE 应该与 Bill 表上的 INSTEAD OF DELETE 触发器有任何关系。
最佳答案
我知道这是一个老问题,但值得回答:
当您的子表定义了一个INSTEAD OF DELETE
触发器时,您不能指定ON DELETE CASCADE
的原因是因为在您的触发器中您可能决定不删除子表表行从而阻碍级联生效。
由于不确定级联是否可行,数据库不知道如何处理这种情况,因此将问题留给开发人员解决。
关于sql-server - INSTEAD OF DELETE 触发器与 ON DELETE CASCADE FK 冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6456739/
我写了这个课: class StaticList { private: int headFree; int headList; int locNe
我目前正在使用 SQL Server Management Studio 2005,我遇到了一些问题,但首先是我的 DB 架构的摘录(重要的): imghack link to the image 我
范围:两个表。创建新顾客时,他们会将一些有关他们的信息存储到第二个表中(这也是使用触发器完成的,它按预期工作)。这是我的表结构和关系的示例。 表 1-> 赞助人 +-----+---------+--
我想知道,在整个程序中,我使用了很多指向 cstrings 的 char* 指针,以及其他指针。我想确保在程序完成后删除所有指针,即使 Visual Studio 和 Code Blocks 都为我做
考虑以下代码: class Foo { Monster* monsters[6]; Foo() { for (int i = 0; i < 6; i++)
关于 this page , 是这么写的 One reason is that the operand of delete need not be an lvalue. Consider: delet
我无法在 DELETE CASCADE ON UPDATE CASCADE 上添加外键约束。 我使用两个简单的表格。 TAB1 有 2 列:ID int(10) unsigned NOT NULL A
你好,有没有办法把它放在一个声明中? DELETE e_worklist where wbs_element = '00000000000000000054TTO'. DELETE e_workli
我有一个表,它是我系统的核心,向我的客户显示的所有结果都存储在那里。它增长得非常快,因此每 3 小时我应该删除早于 X 的记录以提高性能。 仅删除这些记录就足够了,还是应该在删除后运行优化表? 我正在
这个问题在这里已经有了答案: delete vs delete[] operators in C++ (7 个答案) 关闭 9 年前。 做和做有什么区别: int* I = new int[100]
为什么这段代码是错误的?我是否遗漏了有关 delete 和 delete[] 行为的内容? void remove_stopwords(char** strings, int* length) {
当我使用 new [] 申请内存时。最后,我使用 delete 来释放内存(不是 delete[])。会不会造成内存泄漏? 两种类型: 内置类型,如 int、char、double ... 我不确定。
所以在代码审查期间,我的一位同事使用了 double* d = new double[foo]; 然后调用了 delete d。我告诉他们应该将其更改为 delete [] d。他们说编译器不需要基本
范围:两个表。当一个新顾客被创建时,他们将一些关于他们的信息存储到第二个表中(这也是使用触发器完成的,它按预期工作)。这是我的表结构和关系的示例。 表 1-> 赞助人 +-----+---------
C++14 介绍 "sized" versions of operator delete ,即 void operator delete( void* ptr, std::size_t sz ); 和
我正在执行类似的语句 DELETE FROM USER WHERE USER_ID=1; 在 SQLDeveloper 中。 由于用户在许多表中被引用(例如用户有订单、设置等),我们激活了 ON DE
出于某种原因,我找不到我需要的确切答案。我在这里搜索了最后 20 分钟。 我知道这很简单。很简单。但由于某种原因我无法触发触发器.. 我有一个包含两列的表格 dbo.HashTags |__Id_|_
这是我的代码: #include #include #include int main() { setvbuf(stdout, NULL, _IONBF, 0); setvbuf
是否可以在 postgres 中使用单个命令删除所有表中的所有行(不破坏数据库),或者在 postgres 中级联删除? 如果没有,那么我该如何重置我的测试数据库? 最佳答案 is it possib
我想删除一些临时文件的内容,所以我正在开发一个小程序来帮我删除它们。我有这两个代码示例,但我对以下内容感到困惑: 哪个代码示例更好? 第一个示例 code1 删除文件 1 和 2,但第二个示例 cod
我是一名优秀的程序员,十分优秀!