Я использую SQL Server 2012 и пытаюсь вставить данные в несколько таблиц из XML-строки, содержащей данные. Проблема и путаница проистекают из XML, содержащего несколько узлов, поэтому это не только одна запись за раз.TSQL Query Вставка данных из xPath
В связи с этим, я использую метод вывода для вставки данных вместе с идентификатором, поэтому я знаю результат каждой из вставленных записей.
Моя проблема связана со структурой строки XML, она не вставляет все необходимые ему данные.
Вот блок кода я работаю вместе с SQL Fiddle:
Fiddle: http://sqlfiddle.com/#!6/d41d8/24236
DECLARE @xml xml = '<root>
<trainingEventID>572</trainingEventID>
<segment>
<segmentDate>03/03/2015</segmentDate>
<hours>4</hours>
<details>
<locale>653</locale>
<teammates>3</teammates>
<leaders>4</leaders>
</details>
<details>
<locale>655</locale>
<teammates>44</teammates>
<leaders>55</leaders>
</details>
<details>
<locale>657</locale>
<teammates>55</teammates>
<leaders>66</leaders>
</details>
<trainers>
<trainer>
<empID>User12341</empID>
</trainer>
</trainers>
</segment>
<segment>
<segmentDate>03/04/2015</segmentDate>
<hours>4</hours>
<details>
<locale>653</locale>
<teammates>3</teammates>
<leaders>4</leaders>
</details>
<details>
<locale>655</locale>
<teammates>44</teammates>
<leaders>55</leaders>
</details>
<details>
<locale>657</locale>
<teammates>55</teammates>
<leaders>66</leaders>
</details>
<trainers>
<trainer>
<empID>User1234</empID>
</trainer>
</trainers>
</segment>
<segment>
<segmentDate>03/13/2015</segmentDate>
<hours>4</hours>
<details>
<locale>653</locale>
<teammates>3</teammates>
<leaders>4</leaders>
</details>
<details>
<locale>655</locale>
<teammates>44</teammates>
<leaders>55</leaders>
</details>
<details>
<locale>657</locale>
<teammates>55</teammates>
<leaders>66</leaders>
</details>
<trainers>
<trainer>
<empID>User1234</empID>
</trainer>
</trainers>
</segment>
</root>'
-- Declare our temp tables
DECLARE @tmpSeg TABLE (teSegmentID INT, trainingEventID INT, segmentDate DATE, nonProdHrs int);
DECLARE @tmpEvents TABLE (teSegmentID INT IDENTITY(1,1), trainingEventID INT, segmentDate DATE, nonProdHrs INT);
-- First, Insert the main segments
INSERT INTO @tmpEvents(trainingEventID, segmentDate, nonProdHrs)
OUTPUT Inserted.teSegmentID, Inserted.trainingEventID, Inserted.segmentDate, Inserted.nonProdHrs INTO @tmpSeg
SELECT ParamValues.x1.value('../trainingEventID[1]', 'INT'),
ParamValues.x1.value('(segmentDate/text())[1]', 'DATE'),
ParamValues.x1.value('(hours/text())[1]', 'INT')
FROM @xml.nodes('/root/segment') AS ParamValues(x1);
SELECT * FROM @tmpSeg
-- Now, we join on our temp table and insert the Segment Details
SELECT s.teSegmentID,
ParamValues.x1.value('(details/locale/text())[1]', 'INT') AS localeID,
ParamValues.x1.value('(details/teammates/text())[1]', 'INT') AS teammates,
ParamValues.x1.value('(details/leaders/text())[1]', 'INT') AS leaders,
ParamValues.x1.value('(../trainingEventID/text())[1]', 'INT') AS eventID,
ParamValues.x1.value('(segmentDate/text())[1]', 'DATE') AS date,
ParamValues.x1.value('(hours/text())[1]', 'INT') AS hours
FROM @tmpSeg AS s
INNER JOIN @xml.nodes('/root/segment') AS ParamValues(x1)
ON s.trainingEventID = ParamValues.x1.value('(../trainingEventID/text())[1]', 'INT')
AND s.segmentDate = ParamValues.x1.value('(segmentDate/text())[1]', 'DATE')
AND s.nonProdHrs = ParamValues.x1.value('(hours/text())[1]', 'INT')
Как вы можете видеть из структуры XML, он разбивается на части. Существует segment
, а затем внутри сегмента может быть несколько Details
Узлы.
Первым шагом в запросе является создание всех сегментов, которые работают нормально. Каждый сегмент создается, а Identity хранится в таблице temp с выхода.
Далее, мне нужно создать записи для каждого узла данных, используя Identity его родительского сегмента. Я делаю это, объединяя временную таблицу с выходом некоторых своих данных, чтобы получить необходимую информацию.
Проблема с этим связана с несколькими узлами details
, он имеет доступ только к первому и сохраняет свои данные.
Результат в последнем утверждении с использованием этого примера должен содержать 9 записей. На каждом сегменте есть 3 details
узлов и всего 3 сегмента.
Не знаете, как это осуществить, но это сводит меня с ума.
Спасибо за любую помощь.
Если я чего-то не упускаю, вы выбираете первое значение из возвращаемого времени Xpath, которое вы делаете [1]. Где бы вы ожидали получить [2]? – TheNorthWes
Во второй части запроса, где я просто выбираю вывод и присоединяюсь к tmpTable, он получает доступ только к первому узлу с данными, где всего 3 сегмента. Проблема исходит из этого фрагмента кода. Я считаю, что 'INNER JOIN @ xml.nodes ('/ root/segment') AS ParamValues (x1)' как его соединение на уровне сегмента, а затем поиск в 'details'. Тем не менее, его единственный поиск в первом узле деталей, который он находит, хотя есть более одного. – SBB
Конечным результатом должно быть создание 3 сегментов (в настоящее время это делается), а затем в отдельной таблице 9 записей «детали», которые ссылаются на идентификатор их родительского сегмента в таблице сегментов. – SBB