我正在解决最近在我们的sql server数据库中看到的问题。
表1有一个基于用户定义函数的计算位列,它检查另一个表中是否存在记录,如果不存在则计算结果为0.
表2是由表1的函数搜索的表。表2还使用函数检查约束,以查看表1中的位字段是否设置为1.
这似乎是一种循环依赖。问题是当将一批记录插入表2时,约束失败。逐个插入这些相同的记录允许所有插入通过。我不能为我的生活找出为什么批量插入会导致它失败。任何帮助表示赞赏。
CREATE TABLE [dbo].[tPecosPriceCheckStoreSubcategory](
[PecosPriceCheckID] [int] NOT NULL,
[StoreID] [int] NOT NULL,
[SubcategoryID] [int] NOT NULL,
[UndirectedExpectedScans] [int] NULL,
[PriceMin] [decimal](8, 2) NULL,
[PriceMax] [decimal](8, 2) NULL,
[PastPriceVariancePercent] [decimal](5, 2) NULL,
[ChangeDate] [datetime] NOT NULL,
[IsUndirected] [bit] NOT NULL,
[IsDirected] AS ([dbo].[fnPecosPriceCheckStoreSubcategoryIsDirected]([PecosPriceCheckID],[SubcategoryID])),
CONSTRAINT [PK_tPecosPriceCheckStoreSubcategory] PRIMARY KEY CLUSTERED
(
[PecosPriceCheckID] ASC,
[StoreID] ASC,
[SubcategoryID] ASC
)
ALTER TABLE [dbo].[tPecosPriceCheckStoreSubcategory] ADD CONSTRAINT [DF_IsUndirected] DEFAULT ((0)) FOR [IsUndirected]
GO
CREATE FUNCTION [dbo].[fnPecosPriceCheckStoreSubcategoryIsDirected]
(
@PecosPriceCheckID int,
@SubcategoryID int
)
RETURNS bit
AS
BEGIN
declare @isDirected bit
set @isDirected = 0
if (exists (select 1 from tPecosDirectedPriceCheckItem where PecosPriceCheckID = @PecosPriceCheckID and SubcategoryID = @SubcategoryID ))
begin
set @isDirected = 1
end
return @isDirected
END
CREATE TABLE [dbo].[tPecosDirectedPriceCheckItem](
[ID] [int] IDENTITY(1,1) NOT NULL,
[PecosPriceCheckID] [int] NOT NULL,
[PecosItemID] [int] NOT NULL,
[ItemSortOrder] [int] NOT NULL,
[SubcategoryID] [int] NOT NULL,
[ChangeDate] [datetime] NULL,
CONSTRAINT [PK_tPecosDirectedPriceCheckItem] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
ALTER TABLE [dbo].[tPecosDirectedPriceCheckItem] WITH NOCHECK ADD CONSTRAINT [CK_tPecosDirectedPriceCheckItem_CheckPriceCheckSubcategoryDirected] CHECK (([dbo].[fnCheckDirectedItemPriceCheckSubcategory]([PecosPriceCheckID],[SubcategoryID])=(0)))
GO
ALTER TABLE [dbo].[tPecosDirectedPriceCheckItem] CHECK CONSTRAINT [CK_tPecosDirectedPriceCheckItem_CheckPriceCheckSubcategoryDirected]
GO
CREATE FUNCTION [dbo].[fnCheckDirectedItemPriceCheckSubcategory]
(
@PriceCheckID INT,
@SubcategoryID INT
)
RETURNS BIT
AS
BEGIN
DECLARE @isViolation BIT
SET @isViolation =
CASE WHEN EXISTS (SELECT * FROM tPecosPriceCheckStoreSubcategory WHERE SubcategoryID = @SubcategoryID AND PecosPriceCheckID = @PriceCheckID AND IsDirected = 1)
THEN
0
ELSE
1
END
RETURN @isViolation
END