我有书籍,书籍类别和类别的表格
看起来像这样
Book
Id uniqueidentifier,
Title varchar(255),
Author varchar(255),
Deleted datetime
BookCategory
BookId
CategoryId
Category
Id uniqueidentifier
Name varchar(255)
Deleted datetime
我想编写一个约束,如果该图书的类别存在,则会阻止删除图书
意思是,如果一本书(比如说哈利波特)有一个虚构的类别,那么表BookCategory将同时包括Id' s of course。如果用户想要删除具有特定类别的图书,他将无法执行此操作。
some1可以帮助我吗?
PS 当我删除项目时,我实际上并没有删除它们,而是将属性删除为datetime。
答案 0 :(得分:4)
在编辑之前,这是对原始问题的回答。
您正在寻找外键约束:
alter table BookCategory add constraint fk_BookCategory_Book
foreign key (BookId) references Book(Id);
默认情况下,此类约束不允许您删除具有类别的图书。您可以了解cascading
选项以提供更准确的行为。如果您不提供级联操作,则默认为ON DELETE NO ACTION
,这意味着Book
中的行不会被删除。
答案 1 :(得分:0)
如果我理解,您要做的是限制对表的更新以将记录标记为"已删除"。对表的约束不能这样做,但您可以通过更新触发器来完成此操作。此外,您应该尝试在您的应用程序中处理此逻辑。阅读与您类似的问题:Can an SQL constraint be used to prevent a particular value being changed when a condition holds?
答案 2 :(得分:0)
CREATE TABLE Book
(
Id UNIQUEIDENTIFIER
, Title VARCHAR(255)
, Author VARCHAR(255)
, Deleted DATETIME
);
CREATE TABLE BookCategory
(
BookId UNIQUEIDENTIFIER
, CategoryId UNIQUEIDENTIFIER
);
CREATE TABLE Category
(
Id UNIQUEIDENTIFIER
, Name VARCHAR(255)
, Deleted DATETIME
);
INSERT INTO dbo.Book ( Id
, Title
, Author
, Deleted
)
VALUES ( 'BCF8DE45-D26F-43EE-82CD-9975E35E51B1' -- Id - uniqueidentifier
, 'Harry Potter' -- Title - varchar(255)
, 'RK' -- Author - varchar(255)
, NULL -- Deleted - datetime
);
INSERT INTO dbo.Category ( Id
, Name
, Deleted
)
VALUES ( 'EB6E823D-DFE8-448D-B648-EAE1EFE06358' -- Id - uniqueidentifier
, 'Fantasy' -- Name - varchar(255)
, NULL -- Deleted - datetime
);
INSERT INTO dbo.Category ( Id
, Name
, Deleted
)
VALUES ( '9B53C866-0DAA-4637-8169-5B8885A2E644' -- Id - uniqueidentifier
, 'Category without books' -- Name - varchar(255)
, NULL -- Deleted - datetime
);
INSERT INTO dbo.BookCategory ( BookId
, CategoryId
)
VALUES ( 'BCF8DE45-D26F-43EE-82CD-9975E35E51B1' -- BookId - int
, 'EB6E823D-DFE8-448D-B648-EAE1EFE06358' -- CategoryId - int
);
GO
CREATE TRIGGER trg_Category_Check_Category_Usage
ON Category
INSTEAD OF UPDATE
AS
BEGIN
IF UPDATE(Deleted)
BEGIN
IF EXISTS ( SELECT *
FROM INSERTED i
JOIN dbo.BookCategory AS b ON b.CategoryId = i.Id
WHERE i.Deleted IS NOT NULL
)
THROW 60000, 'record exists', 1;
END;
UPDATE b
SET b.deleted = i.deleted
, b.Name = i.Name
FROM Category b
JOIN INSERTED i ON i.Id = b.Id;
END;
GO
UPDATE dbo.Category SET Deleted = GETDATE()WHERE Name = 'Fantasy'; --error
UPDATE dbo.Category
SET Deleted = GETDATE()
WHERE Name = 'Category without books'; --no error
答案 3 :(得分:-2)
在表类别中为id创建一个主键,并使用外键将其与表bookcategory(categoryid)相关联。这将确保在不删除记录的同时不添加id而不引用父表类别从类别表中也可以。