JSON_VALUE для SQL Server 2012? - PullRequest
       8

JSON_VALUE для SQL Server 2012?

0 голосов
/ 10 октября 2018

Я хочу извлечь значения из строки JSON в SQL.Начал писать функцию для этого, но потом я подумал: «наверняка кто-то другой уже сделал это?».Я был очень взволнован, когда увидел, что сейчас в SQL Server есть функция JSON_VALUE ... но потом очень разочарован, когда понял, что она не была добавлена ​​до 2016 года.: (*

Итак ... Я всередина написания моей собственной версии этой функции. Я уверен, что сначала она будет работать, а потом я буду время от времени получать ошибки, пока не улучшу ее со временем.

Но я надеюсь, что кто-то ужеполучил преимущество в этом и разработал несколько изломов, которые я непременно упущу из виду в моем первом наброске ... и надеюсь, что кто-то здесь может указать мне на это?

1 Ответ

0 голосов
/ 10 октября 2018

Что ж, похоже, никому еще не было что предложить, вот код, который я написал до сих пор.Может быть, это поможет следующему человеку на моем месте.Я решил пойти с отдельными функциями в зависимости от типа значения, которое я получаю.Особо следует отметить, что функция date предназначена для извлечения значения, равного количеству миллисекунд с 1970 года, а десятичная функция имеет параметр, позволяющий указать, указано ли значение в кавычках или нет.

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
...