如何将从一个 table 中的 XML 中提取的字段插入到另一个 table 中?
How to insert fields extracted from XML in one table into another table?
我有一个 table(比如 messages
),其中 primary_key
和 xml_data
。我知道如何从一个 xml_data
值中提取多个值,如下所示:
DECLARE @x XML = 'the XML value'
;WITH XMLNAMESPACES (
'http://somenamespace/document' AS msg,
'http://somenamespace/externalMessage' AS dat
)
SELECT c.value('(dat:delivery_list/dat:identifier)[1]', 'varchar(20)') AS dl_identifier,
c.value('(dat:created_on)[1]', 'datetime2(0)') AS created_on,
c.value('(dat:delivery_list/dat:shipping_date)[1]', 'datetime2(0)') AS shipping_date
FROM @x.nodes('/msg:data/msg:body/msg:request/msg:data/dat:operation/dat:data/dat:external_message') AS t(c)
现在,我想构建另一个 table(比如 heads
),具有相同的 primary_key
和列 dl_identifier
、created_on
,并且 shipping_date
填充了从 messages.xml_data
中提取的信息。它应该只处理新的 messages.xml_data
(尚未完成提取)。
到目前为止,我正在考虑左外连接 tables 来检测丢失的 heads
记录,如下所示:
SELECT m.primary_key,
m.xml_data
FROM messages AS m
LEFT OUTER JOIN heads AS h
ON h.primary_key = m.primary_key
AND m.xml_data IS NOT NULL
WHERE h.primary_key IS NULL
它选择了想要的m.xml_data
。是否可以在不使用游标的情况下将从 m.xml_data
(以及 primary_key
)中提取的值插入到 heads
中?
提供 MCVE 最有帮助。看下面的例子:
--a mockup table to simulate your messages
DECLARE @tblMessages TABLE (ID INT IDENTITY PRIMARY KEY, xml_data XML);
--I insert 4 messages
INSERT INTO @tblMessages VALUES ('<root><test a="test 1.1" /><test a="test 1.2" /></root>')
,('<root><test a="test 2.1" /><test a="test 2.2" /></root>')
,('<root><test a="test 3.1" /></root>')
,('<root><test a="test 4.1" /><test a="test 4.2" /><test a="test 4.3" /></root>');
--a mockup table to simulate your "heads" table
DECLARE @tblExtractedValues TABLE(ID INT IDENTITY PRIMARY KEY
,message_ID INT NOT NULL /*always use names constaints and you might add FOREIGN KEY REFERENCES messages(primary_key)*/
,ExtractedValue_test VARCHAR(100));
--Let's simulate, that messages 1 and 3 are extracted already
INSERT INTO @tblExtractedValues VALUES(1,'test 1.1')
,(1,'test 1.2')
,(3,'test 3.1');
--该语句将从"messages"中的XML中读取值,
--但会忽略那些 ID 存在于另一个 table 中的
-- 你可以用 INSERT
注释掉那行以查看 SELECT 的结果
INSERT INTO @tblExtractedValues(message_ID,ExtractedValue_test)
SELECT m.ID
,t.value('@a','varchar(100)')
FROM @tblMessages m
CROSS APPLY m.xml_data.nodes('/root/test') A(t)
WHERE NOT EXISTS(SELECT 1
FROM @tblExtractedValues ev
WHERE ev.message_ID=m.ID);
--Look at the order of insertion. 1 and 3 have lower IDs than 2 and 4
SELECT * FROM @tblExtractedValues;
我有一个 table(比如 messages
),其中 primary_key
和 xml_data
。我知道如何从一个 xml_data
值中提取多个值,如下所示:
DECLARE @x XML = 'the XML value'
;WITH XMLNAMESPACES (
'http://somenamespace/document' AS msg,
'http://somenamespace/externalMessage' AS dat
)
SELECT c.value('(dat:delivery_list/dat:identifier)[1]', 'varchar(20)') AS dl_identifier,
c.value('(dat:created_on)[1]', 'datetime2(0)') AS created_on,
c.value('(dat:delivery_list/dat:shipping_date)[1]', 'datetime2(0)') AS shipping_date
FROM @x.nodes('/msg:data/msg:body/msg:request/msg:data/dat:operation/dat:data/dat:external_message') AS t(c)
现在,我想构建另一个 table(比如 heads
),具有相同的 primary_key
和列 dl_identifier
、created_on
,并且 shipping_date
填充了从 messages.xml_data
中提取的信息。它应该只处理新的 messages.xml_data
(尚未完成提取)。
到目前为止,我正在考虑左外连接 tables 来检测丢失的 heads
记录,如下所示:
SELECT m.primary_key,
m.xml_data
FROM messages AS m
LEFT OUTER JOIN heads AS h
ON h.primary_key = m.primary_key
AND m.xml_data IS NOT NULL
WHERE h.primary_key IS NULL
它选择了想要的m.xml_data
。是否可以在不使用游标的情况下将从 m.xml_data
(以及 primary_key
)中提取的值插入到 heads
中?
提供 MCVE 最有帮助。看下面的例子:
--a mockup table to simulate your messages
DECLARE @tblMessages TABLE (ID INT IDENTITY PRIMARY KEY, xml_data XML);
--I insert 4 messages
INSERT INTO @tblMessages VALUES ('<root><test a="test 1.1" /><test a="test 1.2" /></root>')
,('<root><test a="test 2.1" /><test a="test 2.2" /></root>')
,('<root><test a="test 3.1" /></root>')
,('<root><test a="test 4.1" /><test a="test 4.2" /><test a="test 4.3" /></root>');
--a mockup table to simulate your "heads" table
DECLARE @tblExtractedValues TABLE(ID INT IDENTITY PRIMARY KEY
,message_ID INT NOT NULL /*always use names constaints and you might add FOREIGN KEY REFERENCES messages(primary_key)*/
,ExtractedValue_test VARCHAR(100));
--Let's simulate, that messages 1 and 3 are extracted already
INSERT INTO @tblExtractedValues VALUES(1,'test 1.1')
,(1,'test 1.2')
,(3,'test 3.1');
--该语句将从"messages"中的XML中读取值,
--但会忽略那些 ID 存在于另一个 table 中的
-- 你可以用 INSERT
注释掉那行以查看 SELECT 的结果
INSERT INTO @tblExtractedValues(message_ID,ExtractedValue_test)
SELECT m.ID
,t.value('@a','varchar(100)')
FROM @tblMessages m
CROSS APPLY m.xml_data.nodes('/root/test') A(t)
WHERE NOT EXISTS(SELECT 1
FROM @tblExtractedValues ev
WHERE ev.message_ID=m.ID);
--Look at the order of insertion. 1 and 3 have lower IDs than 2 and 4
SELECT * FROM @tblExtractedValues;