2015-10-14 80 views
1

我需要替换与字符串中特定键相关联的值。SQL - 在特定值后替换值的第一个实例

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

'{"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. 如何更改查询以在列中的所有行上执行。

这里是我的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('%'[email protected]+'%',@Value) 
DECLARE @EndIndex INT = CHARINDEX('"',SUBSTRING(@Value,@StartIndex + @LengthOfKeyToFind, LEN(@Value))) -1 

SELECT STUFF(@Value, @StartIndex + @LengthOfKeyToFind, @EndIndex, 'UpdatedValue') 
+2

该字符串从哪里来?看起来很奇怪,你有一个数据库管理系统,你可以简单地拥有一个键值表,并且更新会非常简单,但是你正在处理一个你试图解析的字符串。这样的字符串操作可能会比DBMS更容易,而使用真正的编程语言。 –

+0

@ThorstenKettner这是一个需要应用于单个表的一次性脚本(错误修复)。数据只是“记录”我们需要存储的数据,因此仅用于只读目的。它不能也不应该作为DBMS中的其他任何东西存储。 – JBond

+0

也许你可以解析你的json然后修改。看看这个:https://www.simple-talk.com/sql/t-sql-programming/consuming-json-strings-in-sql-server/ –

回答

1

创建UDF返回更新的列值:

CREATE FUNCTION dbo.UpdateKeyValue(@Value NVARCHAR(MAX), 
            @KeyToFind NVARCHAR(100), 
            @ValueToUpdate NVARCHAR(100)) 
    RETURNS NVARCHAR(MAX) 
AS 
BEGIN 
    DECLARE @pattern NVARCHAR(105) = '%"'[email protected]+'":"%' 
    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在以太的评论。他对一次性光标的评论使得它具有良好的一次性意义。

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, @[email protected]+1, len(colname)) from tablename) 

select @before + substring(colname, @start, @numchars) + @after 
from tablename 
相关问题