Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在触发器完成之前,SQL Server触发器逻辑不再绕过外键检查_Sql_Sql Server_Triggers_Foreign Keys_Cascade - Fatal编程技术网

在触发器完成之前,SQL Server触发器逻辑不再绕过外键检查

在触发器完成之前,SQL Server触发器逻辑不再绕过外键检查,sql,sql-server,triggers,foreign-keys,cascade,Sql,Sql Server,Triggers,Foreign Keys,Cascade,这里有一个简单的例子,说明我以前已经实现了很多次,但现在不起作用 我有一个名为tblCompany的SQL Server表,同一个表中有两个外键-tblEmployee 外键1=tblCompany.Name+tblCompany.SystemAdminName=tblEmployee.CompanyName+tblEmployee.Name 外键2=tblCompany.Name+tblCompany.LocationAdminName=tblEmployee.CompanyName+tblE

这里有一个简单的例子,说明我以前已经实现了很多次,但现在不起作用

我有一个名为tblCompany的SQL Server表,同一个表中有两个外键-tblEmployee

外键1=tblCompany.Name+tblCompany.SystemAdminName=tblEmployee.CompanyName+tblEmployee.Name

外键2=tblCompany.Name+tblCompany.LocationAdminName=tblEmployee.CompanyName+tblEmployee.Name

当我引入这些外键并将两者设置为级联更新和/或删除时,我得到以下错误

在表“tblEmployee”上引入外键约束“FK\u tblEmployee\u tblCompany1”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束

解决方案是将其中一个外键设置为不级联删除或更新,并创建一个触发器来执行此操作

触发器看起来像这样

CREATE TRIGGER dbo.trgrEmployeeUpd
ON dbo.tblEmployee
AFTER UPDATE
BEGIN

IF UPDATE(Name)
UPDATE c
SET c.LocationAdminName = i.Name
FROM tblCompany c
JOIN DELETED d ON d.CompanyName = c.Name AND d.Name = c.LocationAdminName
JOIN INSERTED i ON i.SurrogateKey = d.SurrogateKey

END
在SQLServer2008R2 Express上,在更新和触发器完成之前,暂时忽略两个表的引用完整性,从而实现了这一点。我现在在SQL Server 2012 Web上,发现一个引用完整性错误

编辑

以防万一,任何人都可以找到一个比我自己处理引用完整性更好的解决方案,这里是真正的表,它缺少下面SQL中隔离的大多数字段,并带有错误消息

USE Test
GO
/****** Object:  Table [dbo].[tblClientPlace]    Script Date: 16/06/2014 12:47:41 ******/

CREATE TABLE [dbo].[tblClientPlace](
[CompanyName] [varchar](50) NOT NULL,
[LocationName] [varchar](30) NOT NULL,
[Name] [varchar](20) NOT NULL,
[SurrogateKey] [int] IDENTITY(1,1) NOT NULL,
 CONSTRAINT [PK_tblPersonPlace] PRIMARY KEY CLUSTERED 
(
[CompanyName] ASC,
[LocationName] ASC,
[Name] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[tblAttendanceClientPlaceMapping](
[CompanyName] [varchar](50) NOT NULL,
[WorkingLocationName] [varchar](30) NOT NULL,
[WorkingClientPlaceName] [varchar](20) NOT NULL,
[AttendanceLocationName] [varchar](30) NOT NULL,
[AttendanceClientPlaceName] [varchar](20) NOT NULL,
CONSTRAINT [PK_tblAttendanceClientPlaceMapping] PRIMARY KEY CLUSTERED 
(
[CompanyName] ASC,
[WorkingLocationName] ASC,
[WorkingClientPlaceName] ASC,
[AttendanceLocationName] ASC,
[AttendanceClientPlaceName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[tblAttendanceClientPlaceMapping]  WITH CHECK ADD  CONSTRAINT [FK_tblAttendanceClientPlaceMapping_tblClientPlace] FOREIGN KEY([CompanyName], [WorkingLocationName], [WorkingClientPlaceName])
REFERENCES [dbo].[tblClientPlace] ([CompanyName], [LocationName], [Name])
ON UPDATE CASCADE
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[tblAttendanceClientPlaceMapping] CHECK CONSTRAINT [FK_tblAttendanceClientPlaceMapping_tblClientPlace]
GO

ALTER TABLE [dbo].[tblAttendanceClientPlaceMapping]  WITH CHECK ADD  CONSTRAINT [FK_tblAttendanceClientPlaceMapping_tblClientPlace1] FOREIGN KEY([CompanyName], [AttendanceLocationName], [AttendanceClientPlaceName])
REFERENCES [dbo].[tblClientPlace] ([CompanyName], [LocationName], [Name])
GO

ALTER TABLE [dbo].[tblAttendanceClientPlaceMapping] CHECK CONSTRAINT [FK_tblAttendanceClientPlaceMapping_tblClientPlace1]
GO

CREATE TRIGGER [dbo].[trgrClientPlaceUpd] 
ON  [dbo].[tblClientPlace] 
AFTER UPDATE
AS 
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

IF UPDATE(Name) OR UPDATE(LocationName)
BEGIN 
UPDATE acpm 
SET AttendanceLocationName = i.LocationName, AttendanceClientPlaceName = i.Name
FROM tblAttendanceClientPlaceMapping acpm
JOIN DELETED d ON d.CompanyName = acpm.CompanyName AND d.LocationName = acpm.AttendanceLocationName AND d.Name = acpm.AttendanceClientPlaceName
JOIN INSERTED i ON i.SurrogateKey = d.SurrogateKey
END

END
GO

INSERT INTO tblClientPlace (CompanyName,LocationName,Name)
VALUES('Hill Valley Cleaners','Hill Valley','Biff Tannen')

INSERT INTO tblClientPlace (CompanyName,LocationName,Name)
VALUES('Hill Valley Cleaners','Hill Valley','Griff Tannen')

INSERT INTO tblAttendanceClientPlaceMapping (CompanyName,WorkingLocationName, WorkingClientPlaceName,AttendanceLocationName,AttendanceClientPlaceName)
VALUES('Hill Valley Cleaners','Hill Valley','Biff Tannen', 'Hill Valley','Griff Tannen')

UPDATE tblClientPlace SET Name = 'Mad Dog Tannen' WHERE CompanyName = 'Hill Valley Cleaners' AND LocationName = 'Hill Valley' AND Name = 'Griff Tannen'
导致错误消息547,第16级,状态0,第1行 UPDATE语句与引用约束FK_tblAttendanceClientPlaceMapping_tblClientPlace1冲突。数据库测试表dbo.tblAttendanceClientPlaceMapping中发生冲突。
该语句已终止。

我已经做了更多的测试,而且该方法似乎在同一服务器上的另一个数据库中也能工作,因此与SQL server的版本无关。1。获取一些tble etc声明代码,单独给出错误,然后将代码和错误剪切并粘贴到问题中。2.PK公司的表应该有一个FK到其employees表的概率大约为零。Vs关于公司和员工FKs的官员的表格。更正。。。这种方法在其他地方也不起作用。最后,我不得不自己管理引用完整性。谢谢philipxy的评论。。。我给出的例子很简单,但我在公司表中有一个指向公司系统管理员的外键。。。对位置admin的引用位于其他位置。真正的问题是其他一些表,我只是想简化它。@philipxy我刚刚按照您的建议添加了真正的独立表。见上文。