2011-12-04 131 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