2011-12-04 134 views
1

我們基本上有一組子記錄,我們將使用它們創建新的父/子記錄,但需要先驗證父記錄是否已經存在存在包含相同的子記錄。以下是詳細信息:檢查在保存父記錄之前是否存在匹配的子記錄

我們有3個表格,其中一個基本上是父代和子代記錄之間的鏈接表。

表A(父表)

Id 
Name 
Desc 

表B(表A和C之間的鏈接表)

Id 
TableAId 
TableCId 

表C(子表)

Id 
StartPosition 
EndPosition 
Percentage 

因此,與那個結構,這裏是一個完整記錄的例子,父表與它的子表有一對多的關係:

表A

(1, 'Sample', 'N/A') 

表B

(1, 1, 1) 
(2, 1, 2) 
(3, 1, 3) 

表C

(1, 1, 3, 0.50) 
(2, 4, 5, 0.30) 
(3, 6, 9, 0.20) 

所以我們然後通過在其中我們解析和投擲到一個臨時表的XML字符串。臨時表的內容是表C的內容,沒有特定的Id。

然後,在我們保存任何新記錄之前,我們需要檢查是否存在具有相同數量的子記錄並且這些子記錄與我們臨時表中的3列匹配的現有表A記錄(沒有ID匹配可能)。

希望這可以很好地解釋,我已經做了很多搜索,找不到任何具體的問題。

+0

爲什麼要使用XML時,SQL Server 2008中引入表值參數(http://msdn.microsoft.com/en-us/library /bb510489.aspx)? – Oded

+0

爲什麼與第三個表格有「一對多關係」? – danihp

+0

@Oded - 因爲我們自2000年以來一直在使用Xml,並且自升級到2008年以來我們沒有更新代碼,並保持一致的解決方案。 – kruegerste

回答

0

你在找什麼叫做關係部門。文章「Divided We Stand: The SQL of Relational Division」提供了使用SQL執行關係劃分的各種技術的很好的總結。對於你的情況,你想在「整除」中列出的技術:

CREATE TABLE tableA (
    Id int PRIMARY KEY, 
    Name varchar(25), 
    [Desc] varchar(255) 
); 
INSERT INTO tableA 
    (Id, Name, [Desc]) 
VALUES 
    (1, 'Sample 1', 'Should match the XML'), 
    (2, 'Sample 2', 'Partial match (should be excluded)'), 
    (3, 'Sample 3', 'Has extra matches (should be excluded)'); 
GO 

CREATE TABLE tableB (
    Id int PRIMARY KEY, 
    TableAId int, 
    TableCId int 
); 
INSERT INTO tableB 
    (Id, TableAId, TableCId) 
VALUES 
    (1, 1, 1), 
    (2, 1, 2), 
    (3, 1, 3), 
    (4, 2, 1), 
    (5, 2, 2), 
    (6, 3, 1), 
    (7, 3, 2), 
    (8, 3, 3), 
    (9, 3, 4); 
GO 

CREATE TABLE tableC (
    Id int PRIMARY KEY, 
    StartPosition int, 
    EndPosition int, 
    Percentage decimal(3,2) 
); 
INSERT INTO tableC 
    (Id, StartPosition, EndPosition, Percentage) 
VALUES 
    (1, 1, 3, 0.50), 
    (2, 4, 5, 0.30), 
    (3, 6, 9, 0.20), 
    (4, 10, 12, 0.10); 
GO 

-- this represents the temp table holding the XML data 
-- we want to match Sample 1 
CREATE TABLE xmlData (
    StartPosition int, 
    EndPosition int, 
    Percentage decimal(3,2) 
); 
INSERT INTO xmlData 
    (StartPosition, EndPosition, Percentage) 
VALUES 
    (1, 3, 0.50), 
    (4, 5, 0.30), 
    (6, 9, 0.20); 
GO 

SELECT 
    b.TableAId 
FROM 
    tableB AS b 
    INNER JOIN 
    tableC AS c 
    ON 
    b.TableCId = c.Id 
    LEFT OUTER JOIN 
    xmlData AS x 
    ON 
    c.StartPosition = x.StartPosition AND 
    c.EndPosition = x.EndPosition AND 
    c.Percentage = x.Percentage 
GROUP BY 
    b.TableAId 
HAVING 
    COUNT(c.Id) = (SELECT COUNT(*) FROM xmlData) AND 
    COUNT(x.StartPosition) = (SELECT COUNT(*) FROM xmlData); 
GO 

DROP TABLE xmlData; 
DROP TABLE tableC; 
DROP TABLE tableB; 
DROP TABLE tableA; 
GO 
+0

謝謝,這看起來像一個體面的解決方案,我會檢查出來。 – kruegerste

+0

完美,像魅力一樣工作,謝謝Cheran。偉大的URL參考啓動。再次感謝。 – kruegerste