我需要替换与字符串中特定键相关联的值。
例如,我有一个这样的字符串:
'{"Key1":"Value1", "Key2":"Value2", "KeyToUpdate":"ValueToUpdate", "Key3":"Value3", "Key4":"Value4"}'
会有一个名为KeyToUpdate
的密钥。它将始终是独一无二的,并始终被引号括起来。然后我需要更新它的相应值。即在冒号后被引号括起来的第一个字符串。在此示例中,值为ValueToUpdate
。同样,冒号分隔符始终存在,值将始终用引号括起来。
我的预期输出,如果我将值更新为UpdatedValue
将是:
'{"Key1":"Value1", "Key2":"Value2", "KeyToUpdate":"UpdatedValue", "Key3":"Value3", "Key4":"Value4"}'
我的问题是:
这是我的SQL:
DECLARE @Value NVARCHAR(256) = '{"Key1":"Value1", "Key2":"Value2", "KeyToUpdate":"ValueToUpdate", "Key3":"Value3", "Key4":"Value4"}'
DECLARE @KeyToFind VARCHAR(256) = '"KeyToUpdate":"'
DECLARE @LengthOfKeyToFind INT = LEN(@KeyToFind)
DECLARE @StartIndex INT = PATINDEX('%'+@KeyToFind+'%',@Value)
DECLARE @EndIndex INT = CHARINDEX('"',SUBSTRING(@Value,@StartIndex + @LengthOfKeyToFind, LEN(@Value))) -1
SELECT STUFF(@Value, @StartIndex + @LengthOfKeyToFind, @EndIndex, 'UpdatedValue')
答案 0 :(得分:1)
创建UDF以返回更新的列值:
CREATE FUNCTION dbo.UpdateKeyValue(@Value NVARCHAR(MAX),
@KeyToFind NVARCHAR(100),
@ValueToUpdate NVARCHAR(100))
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @pattern NVARCHAR(105) = '%"'+@KeyToFind+'":"%'
DECLARE @StartIndex INT = PATINDEX(@pattern, @Value)
-- A little defensive coding
IF @StartIndex = 0 RETURN @Value
DECLARE @EndIndex INT = CHARINDEX('"', @Value, @StartIndex + LEN(@pattern))
RETURN STUFF(@Value,
@StartIndex + LEN(@pattern) - 2,
@EndIndex - (@StartIndex + LEN(@pattern) - 2),
@ValueToUpdate)
END
然后在UPDATE语句中使用它:
UPDATE
SET column = dbo.UpdateKeyValue(column, N'KeyToFind', N'UpdatedValue')
FROM
table
WHERE
column LIKE '%"KeyToFind":"%'
编辑:我花了很多时间格式化我的答案,我的船通过了Tab Alleman在以太的评论。他关于一次性光标的评论很有意义。
答案 1 :(得分:0)
由于这是一次性转型,这应该有效。
declare @start int = (select charindex('"KeyToUpdate"', colname) + len('"KeyToUpdate"') + 1 from tablename)
declare @numchars int = (select charindex(',',
substring(colname, charindex('"KeyToUpdate"', colname) + len('"KeyToUpdate"') + 1, len(colname)) - 1 from tablename)
declare @before varchar(255) = (select substring(colname, 1, charindex('"KeyToUpdate"', colname) - 2) from tablename)
declare @after varchar(255) = (select substring(colname, @start+@numchars+1, len(colname)) from tablename)
select @before + substring(colname, @start, @numchars) + @after
from tablename