使用外键约束从 FILETABLE 中删除
Delete from FILETABLE with foreign key constraint
背景
我正在考虑创建一个简单的网络应用程序,其中一部分将显示与 项目 关联的 图片。我决定研究使用 SQL 服务器的 FILETABLE
功能,这将允许将二进制图像数据直接上传到公开的共享中。因此,有一个用例允许通过 Windows 资源管理器删除文件(FILETABLE
中的行)。此示例复制了问题,该问题源于与 FILETABLE
.
的外键关系
结构
已经使用文件资源管理器将图像添加到 FILETABLE
,path_locator
为 0xFF5354649088A1EFEE8F747CD11030F80800170620
:
CREATE TABLE [dbo].[Image] AS FILETABLE WITH (FileTable_Directory = 'Images');
GO
CREATE TABLE [dbo].[ImageLink] (
[id] INT NOT NULL IDENTITY(1, 1)
,[path_locator] HIERARCHYID NOT NULL
,FOREIGN KEY ([path_locator]) REFERENCES [dbo].[Image] ([path_locator])
);
GO
INSERT INTO [dbo].[ImageLink] ([path_locator]) VALUES (0xFF5354649088A1EFEE8F747CD11030F80800170620);
问题
通过文件资源管理器删除文件后...
...文件从目录中消失,因为 Windows 报告删除成功但该行未从 FILETABLE
.
中删除
然而,当试图通过SQL服务器删除时,抛出熟悉的引用约束冲突错误:
DELETE FROM [dbo].[Image] WHERE [path_locator] = 0xFF5354649088A1EFEE8F747CD11030F80800170620;
Msg 547, Level 16, State 0, Line 69
The DELETE statement conflicted with the REFERENCE constraint "FK__ImageLink__path___5070F446". The conflict occurred in database "FileTableTest", table "dbo.ImageLink", column 'path_locator'.
我向 FILETABLE
添加了一个 AFTER DELETE
触发器,目的是删除引用行,但这也 不会 执行。
问题
- 在通过 Windows Explorer 删除后,如何通过 link table 传播删除?
- 是否有某种 SQL Server/Windows API 挂钩我可以检测并执行处理删除的 DML 代码?
更新#1
来自 BOL,以下部分确认了该行为,但未提供任何进一步信息。
Transactional Semantics
When you access the files in a FileTable by using file I/O APIs, these operations are not associated with any user transactions, and have the following additional characteristics:
- Since non-transacted access to FILESTREAM data in a FileTable is not associated with any transaction, it does not have any specific isolation semantics. However SQL Server may use internal transactions to enforce locking or concurrency semantics on the FileTable data. Any internal transactions of this type are done with read-committed isolation.
看起来,外键有问题。由于该 table 附加有外键,因此您不能简单地删除该行,因为外键约束失败。
因此,首先通过以下方式在 sql 中禁用外键检查:
SET FOREIGN_KEY_CHECKS = 1;
然后尝试删除它 & 是的,不要忘记通过以下方式将外键检查设置为 0:
设置 FOREIGN_KEY_CHECKS = 0;
删除行后。
问题出在外键上。
在您的外键中使用 'ON CASCADE DELETE',因此当您通过文件资源管理器删除时,关联的 ImageLink 也会被删除。
背景
我正在考虑创建一个简单的网络应用程序,其中一部分将显示与 项目 关联的 图片。我决定研究使用 SQL 服务器的 FILETABLE
功能,这将允许将二进制图像数据直接上传到公开的共享中。因此,有一个用例允许通过 Windows 资源管理器删除文件(FILETABLE
中的行)。此示例复制了问题,该问题源于与 FILETABLE
.
结构
已经使用文件资源管理器将图像添加到 FILETABLE
,path_locator
为 0xFF5354649088A1EFEE8F747CD11030F80800170620
:
CREATE TABLE [dbo].[Image] AS FILETABLE WITH (FileTable_Directory = 'Images');
GO
CREATE TABLE [dbo].[ImageLink] (
[id] INT NOT NULL IDENTITY(1, 1)
,[path_locator] HIERARCHYID NOT NULL
,FOREIGN KEY ([path_locator]) REFERENCES [dbo].[Image] ([path_locator])
);
GO
INSERT INTO [dbo].[ImageLink] ([path_locator]) VALUES (0xFF5354649088A1EFEE8F747CD11030F80800170620);
问题
通过文件资源管理器删除文件后...
...文件从目录中消失,因为 Windows 报告删除成功但该行未从 FILETABLE
.
然而,当试图通过SQL服务器删除时,抛出熟悉的引用约束冲突错误:
DELETE FROM [dbo].[Image] WHERE [path_locator] = 0xFF5354649088A1EFEE8F747CD11030F80800170620;
Msg 547, Level 16, State 0, Line 69
The DELETE statement conflicted with the REFERENCE constraint "FK__ImageLink__path___5070F446". The conflict occurred in database "FileTableTest", table "dbo.ImageLink", column 'path_locator'.
我向 FILETABLE
添加了一个 AFTER DELETE
触发器,目的是删除引用行,但这也 不会 执行。
问题
- 在通过 Windows Explorer 删除后,如何通过 link table 传播删除?
- 是否有某种 SQL Server/Windows API 挂钩我可以检测并执行处理删除的 DML 代码?
更新#1
来自 BOL,以下部分确认了该行为,但未提供任何进一步信息。
Transactional Semantics
When you access the files in a FileTable by using file I/O APIs, these operations are not associated with any user transactions, and have the following additional characteristics:
- Since non-transacted access to FILESTREAM data in a FileTable is not associated with any transaction, it does not have any specific isolation semantics. However SQL Server may use internal transactions to enforce locking or concurrency semantics on the FileTable data. Any internal transactions of this type are done with read-committed isolation.
看起来,外键有问题。由于该 table 附加有外键,因此您不能简单地删除该行,因为外键约束失败。
因此,首先通过以下方式在 sql 中禁用外键检查: SET FOREIGN_KEY_CHECKS = 1;
然后尝试删除它 & 是的,不要忘记通过以下方式将外键检查设置为 0: 设置 FOREIGN_KEY_CHECKS = 0; 删除行后。
问题出在外键上。
在您的外键中使用 'ON CASCADE DELETE',因此当您通过文件资源管理器删除时,关联的 ImageLink 也会被删除。