Проверьте, существуют ли соответствующие дочерние записи перед сохранением родительских записей - PullRequest
1 голос
/ 04 декабря 2011

У нас в основном есть набор дочерних записей, в которых мы будем использовать для создания новых родительских / дочерних записей, но сначала нам нужно убедиться, что родительская запись еще не существует и содержит такие же дочерние записи. Вот подробности:

У нас есть 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, без конкретного идентификатора.

Затем, прежде чем сохранять какие-либо новые записи, нам нужно проверить, существует ли существующая запись таблицы А, которая имеет одинаковое количество дочерних записей и соответствует ли эти дочерние записи 3 столбцам в нашей временной таблице (совпадение идентификаторов невозможно) ).

Надеюсь, это достаточно хорошо объяснено, я провел много поисков и не могу найти что-то конкретное для этой проблемы.

1 Ответ

0 голосов
/ 05 декабря 2011

То, что вы ищете, называется реляционным делением .В статье « Разделенное мы стоим: SQL реляционного разделения » дается хорошее резюме различных методов использования 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...