找到其他子串后提取子串

时间:2019-07-10 03:03:41

标签: json sql-server tsql sql-server-2014

我一直在使用Substring,左,右,charindex并不能完全起作用

如果这是列名'Data'中的值(全部为一行)

{"email":{"RecipientId":"usertest","RecipientEmail":"test@test.com","Subject":"This is a test subject heading","RecipientSubject":"A recipient subject"}}

如何执行SELECT语句来查找'Subject'标题,然后获取“ This is a test subject”数据?每条记录的Subject值都不同,所以我根本找不到“ This is a test subject”。

所以最终结果应该是这是SELECT结果的测试对象

2 个答案:

答案 0 :(得分:1)

以下查询应执行您想要的操作:

declare @string varchar(max);
set @string = '{"email":{"RecipientId":"usertest","RecipientEmail":"test@test.com","Subject":"This is a test subject heading","RecipientSubject":"A recipient subject"}}';

select substring(@string,charindex('"Subject":',@string)+11,charindex('"RecipientSubject"',@string)-charindex('"Subject"',@string)-13);

答案 1 :(得分:1)

简单而俗气的方法是这样的:

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来计算值并像使用变量一样使用它。这个想法是:找到起点,然后从那里寻找结束语。但是,只要内容包含(转义的)引号(如

"Subject":"This is \"quoted\" internally"

更通用的方法

从v2016 JSON支持开始。使用这个(或更高版本)的版本,这真的很简单:

使用此原型表进行测试

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);