SQL Server:使用未转义的密钥读取JSON?

时间:2017-10-04 08:12:11

标签: sql-server json

我正在使用的DB中有一些带有未转义密钥的JSON,但似乎SQL服务器无法读取它。有没有办法做到这一点?

示例:

success: function (response) {
             console.log(response);
             var myData = [];
             Ext.Array.forEach(response.data, function (item) {
                 myData.push({
                     name: item.name,
                     email: item.email,
                     phone: item.phone
                 });
             });
             store.load();
}

正确输出SELECT JSON_VALUE('{ "site": "test" }', '$.site')

但是,当我删除test键周围的引号时:

site

无法执行,出现以下错误:

SELECT JSON_VALUE('{ site: "test" }', '$.site')

我知道according to the specs,密钥必须被引号包围才有效,但是其他解析器(例如JSON.NET)设法解码这些字符串就好了,这就是我的问题。

1 个答案:

答案 0 :(得分:1)

也许某种预处理可以帮助..

DECLARE @JSON VARCHAR(MAX) = '{ "pippo": "pippo", site: "test" }'

DECLARE @PATH VARCHAR(255) = 'site'

DECLARE @PATTERN VARCHAR(255) = '%[{ ,]'

;WITH
J AS (
    SELECT STUFF(@JSON, PATINDEX(@PATTERN + @PATH + ':%', @JSON) +1, LEN(@PATH), '"'+@PATH+'"') NEW_JSON, PATINDEX(@PATTERN + @PATH + ':%', @JSON) p
)
SELECT JSON_VALUE(NEW_JSON, '$.'+@PATH) PATH_VAL
FROM J

输出

PATH_VAL
test

您还可以编写一个简单的过程来修复JSON中的所有键,只需将此循环包装在函数或过程中以进行更新

DECLARE @JSON VARCHAR(MAX) = '{    asite: "test", pippo: "site",   site: "test" , "ciccio":"isgood" }'
DECLARE @PATH VARCHAR(255) = '[a-zA-Z]%'
DECLARE @PATTERN VARCHAR(255) = '%[{ ,]'    
DECLARE @P INT = 0, @L INT = 0
DECLARE @W VARCHAR(255) = ''

SET  @P = PATINDEX(@PATTERN + @PATH + ':%', @JSON)  

while @P>0 BEGIN

    SET @P = @P +1 
    SET @L = CHARINDEX(':', @json, @p) - @p
    SET @W = SUBSTRING(@JSON, @P, @L)
    SET @JSON = STUFF(@JSON, PATINDEX(@PATTERN + @W + ':%', @JSON) + 1, LEN(@W), '"' + @W + '"')
    SET @P = PATINDEX(@PATTERN + @PATH + ':%', @JSON)       
    SELECT @P, @JSON
END

输出:

NEW_JSON
{    "asite": "test", "pippo": "site",   "site": "test" , "ciccio":"isgood" }