首页 > 解决方案 > SQL Server 2012 的 JSON_VALUE?

问题描述

我想从 SQL 中的 JSON 字符串中提取值。开始编写一个函数来这样做,但后来我想“肯定有人已经这样做了?”。当我现在看到 SQL Server 中有一个 JSON_VALUE 函数时,我非常兴奋……但当我意识到它直到 2016 年才添加时,我感到非常失望。:(

所以......我正在编写我自己的这个函数版本。我确信它一开始似乎可以工作,然后我偶尔会出错,直到我随着时间的推移完善它。

但我希望有人已经在这方面取得了先机,并解决了我在第一稿中肯定会忽略的一些问题……并希望这里有人能指出我的意思?

标签: jsonsql-server-2012

解决方案


好吧,因为似乎没有人提供任何东西,这是我迄今为止编写的代码。也许它会帮助我的下一个人。我决定根据我要检索的值的类型使用单独的函数。需要特别注意的是 date 函数用于检索自 1970 年以来的毫秒数,而 decimal 函数有一个参数来指定该值是否被引用。

create function [dbo].[GetJsonDateValue](@Key varchar(100), @data nvarchar(max))
returns datetime
as
begin
    declare @keyIdx int = charindex(@Key, @data)
    declare @valueIdx int = @keyIdx + len(@Key) + 2 -- +2 to account for characters between key and value
    declare @termIdx int = charindex(',', @data, @keyIdx)

    -- In case it's last item in an object
    if @termIdx = 0
    set @termIdx = charindex('}', @data, @keyIdx)

    declare @valueLength int = @termIdx - @valueIdx
    declare @secondsSince1970 bigint = cast(substring(@data, @valueIdx, @valueLength) as bigint) / 1000

    declare @retValue datetime = dateadd(s, @secondsSince1970, '19700101')
    return @retValue
end
GO

CREATE function [dbo].[GetJsonDecimalValue](@Key varchar(100), @data nvarchar(max), @quoted bit)
returns decimal(9,2)
as
begin
    declare @keyIdx int = charindex(@Key, @data)
    declare @valueIdx int = @keyIdx + len(@Key) + 2 -- +2 to account for characters between key and value
            + case when @quoted = 1 then 1 else 0 end -- +1 more for quote around value if present
    declare @termIdx int = charindex(case @quoted when 1 then '"' else ',' end, @data, @valueIdx)

    -- In case it's last item in an object and not quoted
    if @quoted = 0 and @termIdx = 0
    set @termIdx = charindex('}', @data, @keyIdx)

    declare @valueLength int = @termIdx - @valueIdx

    if @valueLength = 0
    return null

    declare @retValue decimal(9,2) = cast(substring(@data, @valueIdx, @valueLength) as decimal(9,2))
    return @retValue
end
GO

CREATE function [dbo].[GetJsonStringValue](@Key varchar(100), @data nvarchar(max))
returns varchar(max)
as
begin
    declare @keyIdx int = charindex(@Key, @data)
    declare @valueIdx int = @keyIdx + len(@Key) + 3 -- +3 to account for characters between key and value
    declare @termIdx int = charindex('"', @data, @valueIdx)

    declare @valueLength int = @termIdx - @valueIdx
    declare @retValue varchar(max) = substring(@data, @valueIdx, @valueLength)
    return @retValue
end
GO

推荐阅读