[英]Extracting specific value from large string SQL
I've used a combination of CHARINDEX and SUBSTRING but can't get it working.我使用了 CHARINDEX 和 SUBSTRING 的组合,但无法正常工作。
I get passed a variable in SQL that contains a lot of text but has an email in it.我在 SQL 中传递了一个变量,该变量包含大量文本,但其中包含 email。 I need to extract the email value.
我需要提取 email 值。
I have to use SQL 2008.我必须使用 SQL 2008。
I'm trying to extract the value between "EmailAddress":" and ",我正在尝试提取“EmailAddress”:“和”之间的值,
An example string is here:示例字符串在这里:
{ "Type":test,
"Admin":test,
"User":{
"UserID":"16959191",
"FirstName":"Test",
"Surname":"Testa",
"EmailAddress":"Test.Test@test.com",
"Address":"Test"
}
}
Assuming you can't upgrade to 2016 or higher, you can use a combination of substring
and charindex
.假设您无法升级到 2016 或更高版本,您可以使用
substring
和charindex
的组合。
I've used a common table expression to make it less cumbersome, but you don't have to.我使用了一个通用的表表达式来减少麻烦,但你不必这样做。
DECLARE @json varchar(4000) = '{ "Type":test,
"Admin":test,
"User":{
"UserID":"16959191",
"FirstName":"Test",
"Surname":"Testa",
"EmailAddress":"Test.Test@test.com",
"Address":"Test"
}
}';
WITH CTE AS
(
SELECT @Json as Json,
CHARINDEX('"EmailAddress":', @json) + LEN('"EmailAddress":') As StartIndex
)
SELECT SUBSTRING(Json, StartIndex, CHARINDEX(',', json, StartIndex) - StartIndex)
FROM CTE
Result: "Test.Test@test.com"
结果:
"Test.Test@test.com"
The first hint is: Move to v2016 if possible to use JSON support natively.第一个提示是:如果可能,请移至 v2016,以原生使用 JSON 支持。 v2008 is absolutely outdated...
v2008绝对过时了...
The second hint is: Any string action (and all my approaches below will need some string actions too), will suffer from forbidden characters, unexpected blanks or any other surprise you might find within your data.第二个提示是:任何字符串操作(以及我下面的所有方法也需要一些字符串操作),都会受到禁止字符、意外空白或您可能在数据中发现的任何其他意外的影响。
Try it like this:试试这样:
First I create a mockup scenario to simulate your issue首先,我创建一个模型场景来模拟您的问题
DECLARE @tbl TABLE(ID INT IDENTITY,YourJson NVARCHAR(MAX));
INSERT INTO @tbl VALUES
(N'{ "Type":"test1",
"Admin":"test1",
"User":{
"UserID":"16959191",
"FirstName":"Test1",
"Surname":"Test1a",
"EmailAddress":"Test1.Test1@test.com",
"Address":"Test1"
}
}')
,(N'{ "Type":"test2",
"Admin":"test2",
"User":{
"UserID":"16959191",
"FirstName":"Test2",
"Surname":"Test2a",
"EmailAddress":"Test2.Test2@test.com",
"Address":"Test2"
}
}');
--Starting with v2016 there is JSON support --从 v2016 开始支持 JSON
SELECT JSON_VALUE(t.YourJson, '$.User.EmailAddress')
FROM @tbl t
--String-methods --use CHARINDEX AND SUBSTRING --String-methods --use CHARINDEX AND SUBSTRING
DECLARE @FirstBorder NVARCHAR(MAX)='"EMailAddress":';
DECLARE @SecondBorder NVARCHAR(MAX)='",';
SELECT t.*
,A.Pos1
,B.Pos2
,SUBSTRING(t.YourJson,A.Pos1,B.Pos2 - A.Pos1) AS ExtractedEMail
FROM @tbl t
OUTER APPLY(SELECT CHARINDEX(@FirstBorder,t.YourJson)+LEN(@FirstBorder)) A(Pos1)
OUTER APPLY(SELECT CHARINDEX(@SecondBorder,t.YourJson,A.Pos1)) B(Pos2);
--use a XML trick --使用 XML 技巧
SELECT CAST('<x>' + REPLACE(REPLACE((SELECT t.YourJson AS [*] FOR XML PATH('')),'"EmailAddress":','<mailAddress value='),',',' />') + '</x>' AS XML)
.value('(/x/mailAddress/@value)[1]','nvarchar(max)')
FROM @tbl t
Some explanations:一些解释:
APPLY
.APPLY
。 The advantage is, that you can use the computed positions like a variable.<mailAddress>
with an attribute value
.value
的<mailAddress>
。 We can use the native XML method .value()
to retrieve the value you are asking for:.value()
来检索您要求的值: An intermediate XML looks like this:中间 XML 如下所示:
<x>{ "Type":"test1" />
"Admin":"test1" />
"User":{
"UserID":"16959191" />
"FirstName":"Test1" />
"Surname":"Test1a" />
<mailAddress value="Test1.Test1@test.com" />
"Address":"Test1"
}
}</x>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.