如何解决如果值不在另一个表中,如何防止插入 SQL Server 表?
假设我有两个 SQL Server 表。一个包含“瞬态”数据 - 随着填充表的外部数据发生变化,记录被插入、更新和删除。
我有另一个表使用该表中的数据,我需要确保在尝试插入时在该表中找到其中一个列值。
表 #1 - Widgets
:
CREATE TABLE [dbo].[Widgets]
(
[id] [int] NOT NULL,[widget_attr_1] [int] NULL,[widget_attr_2] [varchar](10) NOT NULL,CONSTRAINT [PK_Table_1]
PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
表 #2 - Transactions
:
CREATE TABLE [dbo].[Transactions]
(
[id] [int] IDENTITY(1,1) NOT NULL,[widget_id] [int] NOT NULL,[transaction_data_1] [varchar](50) NOT NULL,PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
因此,在上面的示例中,我需要确保 widget_id
位于 dbo.Widgets
中,否则会引发错误。我不能使用从 Transactions
到 Widgets
的外键,因为 Transactions
记录是永久性的,当尝试删除 Widget
时,它会失败,因为它被外键引用了。
我可以在插入前使用 CHECK
约束查找 Widgets
表中的值吗?或者也许是一个查找值并在它不存在时抛出错误的触发器?我无法弄清楚这两种方法如何工作以及可能的性能影响是什么。在此处寻找最佳做法。
提前致谢!
解决方法
FOREIGN KEY
是 CHECK CONSTRAINT
的一种。我建议您在 EXISTS
语句中添加一个 INSERT
子句,这样您不想插入的行就不会被插入。在伪 SQL 中:
INSERT INTO dbo.Transactions (widget_id,transaction_data_1)
SELECT widget_id,transaction_data_1
FROM (VALUES(...))V((widget_id,transaction_data_1)
WHERE EXISTS (SELECT 1
FROM dbo.widgets w
WHERE w.widget_id = v.widget_id);
如果您需要抛出错误,您可以使用如下所示的 TRIGGER
,只需注意,如果表 widgets
中甚至不存在 1 个值,则 整个 INSERT
将失败:
CREATE TRIGGER dbo.trg_fk_TranasctionWidget
ON dbo.Transactions
AFTER INSERT
AS
IF EXISTS (SELECT 1
FROM inserted i
LEFT JOIN dbo.widgets w ON i.widget_id = w.widget_id
WHERE w.widget_id IS NULL)
--Change the error number to one suitable for your environment
THROW 73246,N'The INSERT statement conflict with the trigger constraint trg_fk_TranasctionWidget. The conflict occured on the table "dbo.Transactions",column "widget_id".',16;
GO
不过,就像@MartinSmith 有 commented 一样,您似乎真的应该考虑级联。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。