我有一个数据类型为nvarchar(max)
的字符串,如下所示:
declare @cbCheckdate nvarchar(max) ='
{"request_id":"364202","final_decision":"FAIL","derived_Attribute_1":"PASS|Number of active MFI :1",
"derived_Attribute_4":"PASS|Total Exposure + Applied Amount :53051.0",
"derived_Attribute_3":"PASS|Number of Total Active Institutions :2",
"derived_Attribute_2":"FAIL|Overdue Amount:17984.0","derived_Attribute_5":"PASS|Write off amount:0.0",
"cbResponseMsg":"Final Decision:FAIL || Number of active MFI :1 || Total Exposure + Applied Amount :53051.0
|| Number of Total Active Institutions :2 || FAILOve'
我需要像下面这样截断上面的字符串:
declare @cbCheckdate nvarchar(max) ='{"request_id":"364202","final_decision":"FAIL","derived_Attribute_1":"PASS|Number of active MFI :1",
"derived_Attribute_4":"PASS|Total Exposure + Applied Amount :53051.0",
"derived_Attribute_3":"PASS|Number of Total Active Institutions :2",
"derived_Attribute_2":"FAIL|Overdue Amount:17984.0","derived_Attribute_5":"PASS|Write off amount:0.0"'
基本上,我需要做的是:如果我的字符串包含此单词cbResponseMsg
,那么我需要删除此单词以及其后的所有文本。
此输入可能是JSON格式,因此,如果您使用SQL Server 2016+,则可以使用JSON_MODIFY()
函数从输入JSON中删除cbResponseMsg
键:
声明:
DECLARE @cbCheckdate nvarchar(max) = '{
"request_id":"364202",
"final_decision":"FAIL",
"derived_Attribute_1":"PASS|Number of active MFI :1",
"derived_Attribute_4":"PASS|Total Exposure + Applied Amount :53051.0",
"derived_Attribute_3":"PASS|Number of Total Active Institutions :2",
"derived_Attribute_2":"FAIL|Overdue Amount:17984.0",
"derived_Attribute_5":"PASS|Write off amount:0.0",
"cbResponseMsg":"Final Decision:FAIL || Number of active MFI :1 || Total Exposure + Applied Amount :53051.0 || Number of Total Active Institutions :2 || FAILOve"
}'
SELECT @cbCheckdate = JSON_MODIFY(@cbCheckdate, '$.cbResponseMsg', NULL)
SELECT @cbCheckdate
结果:
{
"request_id":"364202",
"final_decision":"FAIL",
"derived_Attribute_1":"PASS|Number of active MFI :1",
"derived_Attribute_4":"PASS|Total Exposure + Applied Amount :53051.0",
"derived_Attribute_3":"PASS|Number of Total Active Institutions :2",
"derived_Attribute_2":"FAIL|Overdue Amount:17984.0",
"derived_Attribute_5":"PASS|Write off amount:0.0"
}
您可以这样做
set @cbCheckdate = left(@cbCheckdate, CHARINDEX('cbResponseMsg', @cbCheckdate) -2) select @cbCheckdate
由于您使用的是SQL Server 2014,并且还没有内置的JSON支持,因此我可能会为此编写一个小函数:
CREATE OR ALTER FUNCTION dbo.TruncateAfter(@Input NVARCHAR(MAX), @Delimiter NVARCHAR(100))
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @Result NVARCHAR(MAX);
DECLARE @DelimiterPos INT;
SET @DelimiterPos = CHARINDEX(@Delimiter, @Input);
IF (@DelimiterPos > 0)
SET @Result = TRIM(LEFT(@Input, @DelimiterPos - 1));
ELSE
SET @Result = @Input;
RETURN @Result;
END
现在,您可以使用两个参数调用此函数-输入和要查找的“定界符”。如果找到定界符,则从其位置开始的所有文本都会被截断-如果定界符未出现在输入中,则返回整个输入:
DECLARE @cbCheckdate NVARCHAR(MAX) = N'
{"request_id":"364202","final_decision":"FAIL","derived_Attribute_1":"PASS|Number of active MFI :1",
"derived_Attribute_4":"PASS|Total Exposure + Applied Amount :53051.0",
"derived_Attribute_3":"PASS|Number of Total Active Institutions :2",
"derived_Attribute_2":"FAIL|Overdue Amount:17984.0","derived_Attribute_5":"PASS|Write off amount:0.0",
"cbResponseMsg":"Final Decision:FAIL || Number of active MFI :1 || Total Exposure + Applied Amount :53051.0
|| Number of Total Active Institutions :2 || FAILOve'
DECLARE @Delimiter NVARCHAR(MAX) = N'cbResponseMsg';
SELECT
dbo.TruncateAfter (@cbCheckdate, @Delimiter)
应返回所需的输出。
这是使用内置函数stuff
,charindex
,reverse
,len
和sign
的无用户定义功能的安全方法:
declare @cbCheckdate nvarchar(max) ='
{"request_id":"364202","final_decision":"FAIL","derived_Attribute_1":"PASS|Number of active MFI :1",
"derived_Attribute_4":"PASS|Total Exposure + Applied Amount :53051.0",
"derived_Attribute_3":"PASS|Number of Total Active Institutions :2",
"derived_Attribute_2":"FAIL|Overdue Amount:17984.0","derived_Attribute_5":"PASS|Write off amount:0.0",
"cbResponseMsg":"Final Decision:FAIL || Number of active MFI :1 || Total Exposure + Applied Amount :53051.0
|| Number of Total Active Institutions :2 || FAILOve';
declare @delimiter nvarchar(100) = '"cbResponseMsg"';
SELECT REVERSE(
STUFF(
REVERSE(@cbCheckdate),
1,
CHARINDEX(REVERSE(@delimiter), REVERSE(@cbCheckdate)) +
LEN(@delimiter) * SIGN(CHARINDEX(@delimiter, @cbCheckdate)),
'')
)
这里是从内到外的细分:
CHARINDEX(@delimiter, @cbCheckdate)
将为SIGN
返回0
,为正数返回0
,或(与这种情况无关)为负数返回1
。-1
将返回CHARINDEX(REVERSE(@delimiter), REVERSE(@cbCheckdate)) +
LEN(@delimiter) * SIGN(CHARINDEX(@delimiter, @cbCheckdate))
,如果找不到分隔符,或者是表示分隔符开头到字符串结尾之间的字符数的正整数。0
函数将一个空字符串放入源字符串中,从第一个字符(STUFF
)开始,并替换它作为第三个参数使用的字符数。1
结果一次以正确的顺序返回字符串。您可以尝试这个
reverse
尝试作为简单有效的查询:
SELECT
CASE
WHEN @cbCheckdate LIKE '%cbResponseMsg%' THEN LEFT(@cbCheckdate, CHARINDEX('cbResponseMsg', @cbCheckdate)-3)
ELSE @cbCheckdate
END