【问题标题】:Extracting a substring after finding a different substring找到不同的子字符串后提取子字符串
【发布时间】:2019-11-19 14:50:35
【问题描述】:

我一直在玩 Substring, left, right, 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 for that SELECT result

【问题讨论】:

  • 您使用的是哪个数据库?
  • Microsoft SQL Server 2014。使用查询设计器

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


【解决方案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);

【讨论】:

  • 谢谢 :) 效果很好,一步一步完成它是有意义的
  • @user5171795 这可能有效,但也依赖于顺序以及两个键的存在。具有不同键顺序或缺少键顺序的 Json 可能会破坏此...
【解决方案2】:

简单明了的方法是这样的:

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

【讨论】:

    猜你喜欢
    • 2016-04-04
    • 1970-01-01
    • 2021-10-26
    • 2015-06-06
    • 2015-10-19
    • 2012-10-24
    • 2011-07-21
    • 1970-01-01
    相关资源
    最近更新 更多