SQL - 在特定值

时间:2015-10-14 18:48:18

标签: sql sql-server

我需要替换与字符串中特定键相关联的值。

例如,我有一个这样的字符串:

'{"Key1":"Value1", "Key2":"Value2", "KeyToUpdate":"ValueToUpdate", "Key3":"Value3", "Key4":"Value4"}'

会有一个名为KeyToUpdate的密钥。它将始终是独一无二的,并始终被引号括起来。然后我需要更新它的相应值。即在冒号后被引号括起来的第一个字符串。在此示例中,值为ValueToUpdate。同样,冒号分隔符始终存在,值将始终用引号括起来。

我的预期输出,如果我将值更新为UpdatedValue将是:

'{"Key1":"Value1", "Key2":"Value2", "KeyToUpdate":"UpdatedValue", "Key3":"Value3", "Key4":"Value4"}'

我的问题是:

  1. 如何以更简洁/更干净的方式实现此查询
  2. 如何更改查询以对列中的所有行执行。
  3. 这是我的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')
    

2 个答案:

答案 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