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中有效。它不會是一個外鍵,但它至少會檢查你的完整性。