4

XML列中的某些节点值引用已知表的整数主键。是否有可能让SQL Server检查这种外键关系?是否可以为XML中的数据安排外键约束?

+1

如果你想强制这种关系,那么它不属于一个XML文档。 – 2012-03-07 19:01:45

+1

我不明白你的评论。我只需要启用SQL Server的一些机制来检查文档对表键。它如何改变XML文档的想法? – Mike 2012-03-07 19:16:46

+2

如果您想强制执行关键关系,那么您需要将XML分解成表格。 – 2012-03-07 19:24:01

回答

3

答案是肯定的,你可以!

由于您的文档包含固定数量的这种引用的约束,您可以为您创建外键的持久计算列。

CREATE FUNCTION dbo.GetFooRef(@doc XML) 
RETURNS INT 
WITH SCHEMABINDING 
AS 
BEGIN 
    RETURN @doc.value(N'(/doc/foo/@id)[1]','int'); 
END; 

CREATE TABLE Foo(id INT PRIMARY KEY); 

CREATE TABLE Bar(
    doc XML, 
    ref AS (dbo.GetFooRef(doc)) PERSISTED FOREIGN KEY REFERENCES dbo.Foo(id) 
); 

INSERT INTO dbo.Bar(doc) VALUES ('<doc><foo id="1"/></doc>'); 
--The INSERT statement conflicted with the FOREIGN KEY constraint "FK__Bar__ref__ ..." 
INSERT INTO dbo.Foo(id) VALUES (1); 
INSERT INTO dbo.Bar(doc) VALUES ('<doc><foo id="1"/></doc>'); 
+0

酷! SQL Server支持哪些最小版本? – Mike 2015-03-29 04:14:30

+0

我在2014年测试过,所以无法确定。但似乎所需的功能是2005年可用 – 2015-03-30 19:38:16

+0

我应该补充说,如果你的xml实际上有这样的引用的固定数量,你可能想要查看稀疏列和列集作为选项 – 2015-04-01 00:05:58

4

答案是否定的,你不能。

您不能直接在FOREIGN KEY关系中使用XML value()。为了它的乐趣,我尝试创建一个计算列,其结果是调用.value('<some xpath>', 'int')包装在用户定义的函数中。麻烦的是你也不能在FOREIGN KEY关系中使用计算列。

在实际限制之外,您可以尝试执行传入的INSERTUPDATE语句的验证......但这已经成为一个解决方案的混乱。正如Damien所说 - 如果您想强制执行外键约束,这实际上不属于XML文档。

+1

是的,带触发器的解决方案可以工作,而且很难。我需要的是存储半结构化数据,并且我不能像常规外键一样使用参考表的相反方向,并使用查询构建XML。有很多被引用的表,结构是相当随意的。可能我必须寻找代表半结构化数据的另一种方式。 – Mike 2012-03-07 19:28:43

0

我会张贴作为评论,但我没有足够的声誉:D。我认为你可以添加一个约束来返回一个函数的值,该值将在你的xml中有效。它不会是一个外键,但它至少会检查你的完整性。