简单明了的方法是这样的:
SELECT SUBSTRING(
t.YourString
,A.StartPosition
,CHARINDEX('"'
,t.YourString
,A.StartPosition+1) - A.StartPosition
)
FROM @dummyTable t
CROSS APPLY(SELECT CHARINDEX('"Subject":"',t.YourString)+11) A(StartPosition)
我使用APPLY 来计算一个值并像使用变量一样使用它。这个想法是:找到起点并从那里寻找结束语。但这会中断,只要内容包含(转义)引用,如 in
"Subject":"This is \"quoted\" internally"
更通用的方法
从 v2016 开始引入 JSON 支持。有了这个(或更高的)版本,这真的很简单:
使用这个 mockup-table 进行测试
DECLARE @dummyTable TABLE (YourString VARCHAR(1000));
INSERT INTO @dummyTable VALUES('{"email":{"RecipientId":"usertest","RecipientEmail":"test@test.com","Subject":"This is a test subject heading","RecipientSubject":"A recipient subject"}}');
--OPENJSON-方法将为您读取此内容:
SELECT JsonContent.*
FROM @dummyTable t
CROSS APPLY OPENJSON(t.YourString,'$.email')
WITH(RecipientId VARCHAR(100)
,RecipientEmail VARCHAR(100)
,[Subject] VARCHAR(100)
,RecipientSubject VARCHAR(100)) JsonContent;
但是对于较低版本,您需要解决这个问题。这是最简单的,将 JSON 转换为 以属性为中心的 XML,如下所示:
<email RecipientId="usertest" RecipientEmail="test@test.com" Subject="This is a test subject heading" RecipientSubject="A recipient subject" />
我们可以通过一些字符串方法来实现这一点,我必须警告你,有几个陷阱与禁止字符和其他东西......试试吧:
SELECT Casted.ToXml.value('(/email/@RecipientId)[1]','varchar(1000)') AS RecipientId
,Casted.ToXml.value('(/email/@RecipientEmail)[1]','varchar(1000)') AS RecipientEmail
,Casted.ToXml.value('(/email/@Subject)[1]','varchar(1000)') AS [Subject]
,Casted.ToXml.value('(/email/@RecipientSubject)[1]','varchar(1000)') AS RecipientSubject
,Casted.ToXml.query('.') LookHowThisWasTransformed
FROM @dummyTable t
CROSS APPLY
(
SELECT CAST(CONCAT('<email '
,REPLACE(REPLACE(REPLACE(REPLACE(t.YourString,'{"email":{"',''),'}}',''),'","','" '),'":"',' ="')
,' />') AS XML)
) Casted(ToXml);