我有一个SQL查询,它将记录从我传递给它的XML字符串插入表中。该字符串可以包含1个节点或多个节点,因此每个节点都是一个新记录。
这是我的XML字符串:
<root>
<data>
<segment>
<trainingEventID>9</trainingEventID>
<localeID>641</localeID>
<numOfTeammates>12</numOfTeammates>
<nonProdHrs>21</nonProdHrs>
<segmentDate>10/10/2014</segmentDate>
<trainers>
<trainer>
<empID>HUS123</empID>
</trainer>
<trainer>
<empID>Dan123</empID>
</trainer>
</trainers>
</segment>
</data>
<data>
<segment>
<trainingEventID>9</trainingEventID>
<localeID>641</localeID>
<numOfTeammates>12</numOfTeammates>
<nonProdHrs>21</nonProdHrs>
<segmentDate>10/25/2014</segmentDate>
<trainers>
<trainer>
<empID>HUS123</empID>
</trainer>
<trainer>
<empID>Dan123</empID>
</trainer>
</trainers>
</segment>
</data>
</root>
每个segment
都是添加到表格中的新记录。
现在,我有一个名为trainers
的单独表。对于每个培训师,我还需要在该表中插入记录,但它需要具有该段的last inserted record id
。
这是我的问题:
INSERT INTO myTable(trainingEventID, localeID, segmentDate, numofTeammates, nonProdHrs)
SELECT ParamValues.x1.value('trainingEventID[1]', 'INT'),
ParamValues.x1.value('localeID[1]', 'INT'),
ParamValues.x1.value('segmentDate[1]', 'DATE'),
ParamValues.x1.value('numOfTeammates[1]', 'INT'),
ParamValues.x1.value('nonProdHrs[1]', 'FLOAT')
FROM @xml.nodes('/root/data/segment') AS ParamValues(x1);
如何将训练器插入到具有从段插入创建的记录ID的另一个表中?
答案 0 :(得分:1)
在问题中澄清了这一陈述:
对于每个培训师,我还需要在该表中插入一条记录,但它需要具有该段的最后一个插入记录ID。
存在(在问题的评论中找到):
教练表中总共有4条记录,2条段ID为1,另2条段ID为2。
以下内容将此数据插入到具有自动递增ID的相关表中。在示例数据中,我略微改变了EmpID值,以便更清楚地确实它按预期工作。
DECLARE @DocumentID INT, @ImportData XML;
SET @ImportData = N'
<root>
<data>
<segment>
<trainingEventID>9</trainingEventID>
<localeID>641</localeID>
<numOfTeammates>12</numOfTeammates>
<nonProdHrs>21</nonProdHrs>
<segmentDate>10/10/2014</segmentDate>
<trainers>
<trainer>
<empID>HUS123</empID>
</trainer>
<trainer>
<empID>Dan123</empID>
</trainer>
</trainers>
</segment>
</data>
<data>
<segment>
<trainingEventID>9</trainingEventID>
<localeID>641</localeID>
<numOfTeammates>12</numOfTeammates>
<nonProdHrs>21</nonProdHrs>
<segmentDate>10/25/2014</segmentDate>
<trainers>
<trainer>
<empID>HUS1234</empID>
</trainer>
<trainer>
<empID>Dan1234</empID>
</trainer>
</trainers>
</segment>
</data>
</root>';
DECLARE @Segment TABLE (SegmentId INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
TrainingEventID INT NOT NULL, -- Unique
LocaleID INT NOT NULL, -- Unique
NumOfTeammates INT,
NonProdHrs INT,
SegmentDate DATE); -- Unique
-- Ideally create UNIQUE INDEX with the 3 fields noted above
DECLARE @Trainer TABLE (TrainerId INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
SegmentID INT NOT NULL, -- FK to Segment.SegmentID
EmpID VARCHAR(50) NOT NULL);
EXEC sp_xml_preparedocument @DocumentID OUTPUT, @ImportData;
-- First pass: extract "Segment" rows
INSERT INTO @Segment
(TrainingEventID, LocaleID, NumOfTeammates, NonProdHrs, SegmentDate)
SELECT TrainingEventID, LocaleID, NumOfTeammates, NonProdHrs, SegmentDate
FROM OPENXML (@DocumentID, N'/root/data/segment', 2)
WITH (TrainingEventID INT './trainingEventID/text()',
LocaleID INT './localeID/text()',
NumOfTeammates INT './numOfTeammates/text()',
NonProdHrs INT './nonProdHrs/text()',
SegmentDate DATE './segmentDate/text()');
-- Second pass: extract "Trainer" rows
INSERT INTO @Trainer (SegmentID, EmpID)
SELECT seg.SegmentID, trnr.EmpID
FROM OPENXML (@DocumentID, N'/root/data/segment/trainers/trainer', 2)
WITH (TrainingEventID INT '../../trainingEventID/text()',
LocaleID INT '../../localeID/text()',
SegmentDate DATE '../../segmentDate/text()',
EmpID VARCHAR(50) './empID/text()') trnr
INNER JOIN @Segment seg
ON seg.[TrainingEventID] = trnr.[TrainingEventID]
AND seg.[LocaleID] = trnr.[LocaleID]
AND seg.[SegmentDate] = trnr.[SegmentDate];
EXEC sp_xml_removedocument @DocumentID;
-------------------
SELECT * FROM @Segment ORDER BY [SegmentID];
SELECT * FROM @Trainer ORDER BY [SegmentID];
输出:
SegmentId TrainingEventID LocaleID NumOfTeammates NonProdHrs SegmentDate
1 9 641 12 21 2014-10-10
2 9 641 12 21 2014-10-25
TrainerId SegmentID EmpID
1 1 HUS123
2 1 Dan123
3 2 HUS1234
4 2 Dan1234
参考文献: