原答案:
另一种可能的方法是 JSON 转换(正如评论中提到的@PanagiotisKanavos)。您需要将Body数据转换为有效的 JSON 对象,OPENJSON()并使用显式模式解析该对象:
桌子:
CREATE TABLE Data (
Id int,
Body varchar(max)
)
INSERT INTO Data
(Id, Body)
VALUES
(1, 'Status: Completed' + CHAR(13) + CHAR(10) + 'Successful actions count: 106' + CHAR(13) + CHAR(10) + 'Page load count: 105'),
(2, 'Status: Failed' + CHAR(13) + CHAR(10) + 'Successful actions count: 91' + CHAR(13) + CHAR(10) + 'Page load count: 90'),
(3, 'Status: Completed' + CHAR(13) + CHAR(10) + 'Successful actions count: 40' + CHAR(13) + CHAR(10) + 'Page load count: 44')
陈述:
SELECT j.*
FROM Data d
CROSS APPLY OPENJSON (CONCAT('{"', REPLACE(REPLACE(d.Body, ': ', '":"'), CHAR(13) + CHAR(10), '","'), '"}')) WITH (
Status varchar(100) '$.Status',
Successful_Actions_Count int '$."Successful actions count"',
Page_Load_Count int '$."Page load count"'
) j
结果:
-------------------------------------------------------
Status Successful_Actions_Count Page_Load_Count
-------------------------------------------------------
Completed 106 105
Failed 91 90
Completed 40 44
如果列中有NULL值,则Body可以尝试使用以下方法:
SELECT d.Id, j.*
FROM Data d
OUTER APPLY OPENJSON (
CASE
WHEN d.Body IS NULL THEN '{}'
ELSE CONCAT('{"', REPLACE(REPLACE(d.Body, ': ', '":"'), CHAR(13) + CHAR(10), '","'), '"}')
END
) WITH (
Status varchar(100) '$.Status',
Successful_Actions_Count int '$."Successful actions count"',
Page_Load_Count int '$."Page load count"'
) j
如果Body列中的数据以新行结尾,则需要添加一个额外的key:value对 ( "x": "0") 以使 JSON 有效:
SELECT d.Id, j.*
FROM Data d
OUTER APPLY OPENJSON (
CASE
WHEN d.Body IS NULL THEN '{}'
ELSE CONCAT('{"', REPLACE(REPLACE(d.Body, ': ', '":"'), CHAR(13) + CHAR(10), '","'), 'x": "0"}')
END
) WITH (
Status varchar(100) '$.Status',
Successful_Actions_Count int '$."Successful actions count"',
Page_Load_Count int '$."Page load count"'
) j
更新:
如果您想实现触发器(我认为您需要一种不同类型的触发器),接下来的代码行可能会有所帮助。
表和触发器:
CREATE TABLE MailArchive (
Id int,
Mail_Body varchar(max),
Status varchar(100),
Successful_actions_count int,
Page_load_count int
);
CREATE TRIGGER BodyParseTrigger ON MailArchive INSTEAD OF INSERT
AS BEGIN
INSERT INTO MailArchive (ID, Mail_Body, Status, Successful_Actions_Count, Page_Load_Count)
SELECT i.ID, i.Mail_Body, j.Status, j.Successful_Actions_Count, j.Page_Load_Count
FROM Inserted i
OUTER APPLY OPENJSON (CONCAT('{"', REPLACE(REPLACE(i.Mail_Body, ': ', '":"'), CHAR(13) + CHAR(10), '","'), '"}'))
WITH (
Status varchar(100) '$.Status',
Successful_Actions_Count int '$."Successful actions count"',
Page_Load_Count int '$."Page load count"'
) j
END
陈述:
INSERT INTO MailArchive
(Id, Mail_Body)
VALUES
(1, 'Status: Completed' + CHAR(13) + CHAR(10) + 'Successful actions count: 106' + CHAR(13) + CHAR(10) + 'Page load count: 105')
SELECT *
FROM MailArchive
结果:
---------------------------------------------------------------------------------------
Id Mail_Body Status Successful_actions_count Page_load_count
---------------------------------------------------------------------------------------
1 Status: Completed Completed 106 105
Successful actions count: 106
Page load count: 105
如何删除额外的换行符:
如果您的Mail_Body列包含额外的换行符,您可以尝试更改转换以消除可能的 JSON 解析错误。现在,转换的结果将是 JSON 数组 ( ["Status: Completed", ...]),而不是 JSON 对象 ( {"Status":"Completed", ...})。在这种情况下,您应该使用OPENJSON()默认模式(不带WITH子句)并使用MAX()来获得预期的结果:
带有额外换行符的表格和数据:
DECLARE @text1 varchar(max) =
'Status: Completed' + CHAR(13) + CHAR(10) +
'Successful actions count: 106' + CHAR(13) + CHAR(10) +
'Page load count: 105' + CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10)
DECLARE @text2 varchar(max) =
'Agent did not meet defined success criteria on this run.' + CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10) +
'Status: Completed' + CHAR(13) + CHAR(10) +
'Successful actions count: 106' + CHAR(13) + CHAR(10) +
'Page load count: 105' + CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10)
CREATE TABLE Data (
Id int,
Mail_Body varchar(max)
)
INSERT INTO Data
(Id, Mail_Body)
VALUES
(1, @text1),
(2, @text2)
声明:
SELECT d.Id, j.[Status], j.Successful_actions_count, j.Page_load_count
FROM Data d
OUTER APPLY (
SELECT
MAX(CASE WHEN CHARINDEX('Status:', [value]) = 1 THEN REPLACE([value], 'Status:', '') END) AS [Status],
MAX(CASE WHEN CHARINDEX('Successful actions count:', [value]) = 1 THEN REPLACE([value], 'Successful actions count:', '') END) AS [Successful_actions_count],
MAX(CASE WHEN CHARINDEX('Page load count:', [value]) = 1 THEN REPLACE([value], 'Page load count:', '') END) AS [Page_load_count]
FROM OPENJSON(CONCAT('["', REPLACE(d.Mail_Body, CHAR(13) + CHAR(10), '","'), '"]'))
) j
结果:
-----------------------------------------------------------
Id Status Successful_actions_count Page_load_count
-----------------------------------------------------------
1 Completed 106 105
2 Completed 106 105