Sql 如何截断特定单词后的字符串?
我有一个数据类型字符串Sql 如何截断特定单词后的字符串?,sql,sql-server,tsql,sql-server-2014,truncate,Sql,Sql Server,Tsql,Sql Server 2014,Truncate,我有一个数据类型字符串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_
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\u 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 Server2014,并且还没有内置的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)),
'')
)
以下是由内而外的细分:
如果未找到分隔符,则返回0;如果在字符串中找到分隔符,则返回正整数CHARINDEX(@delimiter,@cbCheckdate)
对于SIGN
将返回0
,对于正数将返回0
,对于负数将返回1
-1
将返回CHARINDEX(反向(@delimiter),反向(@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
将此作为一个简单、有效的查询进行尝试:
SELECT
LEFT(@cbCheckdate, CHARINDEX('cbResponseMsg', @cbCheckdate)-3)
WHERE
@cbCheckdate LIKE '%cbResponseMsg%'
UNION ALL
SELECT
@cbCheckdate
WHERE
@cbCheckdate NOT LIKE '%cbResponseMsg%'
您的SQL Server版本是什么?SQL 2014版“JSON_MODIFY”不是公认的内置函数名。@Mar1009是的,我在回答中提到了这一点,SQL Server 2016中引入了JSON支持。如果您的文本是有效的JSON,您可能需要搜索UDF来解析此JSON,或者尝试使用另一种方法,可能基于字符串或XML转换。如果
@cbCheckdate
字符串不包含cbResponseMsg
,则此方法无效-在这种情况下,您会得到:Msg 537,级别16,状态3,第3行传递给LEFT或SUBSTRING函数的长度参数无效。
我不希望在用户定义的标量函数中这样做。它们因性能问题而臭名昭著。@ZoharPeled:据我所知,只要不在标量函数中“隐藏”任何实际的数据访问(使用选择
),性能就不会真正成为问题。这个存储函数只对输入参数进行操作,不会以这种方式执行任何“繁重的操作”——因此我非常确定它应该是很好的注释:,这意味着在某些情况下,此代码可能会为left
函数抛出错误。这不是整数的行为吗?在将其用于(var)charI时从未出现过问题我不认为数据类型是问题所在。。。我只知道不能保证短路,不知道具体情况。