SQL:自定义函数F_JSON_VALUE同 JSON_VALUE

详细代码如下:

 

IF OBJECT_ID('F_JSON_VALUE','FN')>0 
 drop FUNCTION F_JSON_VALUE;

GO 

CREATE FUNCTION F_JSON_VALUE( @JSON_OBJECT NVARCHAR(4000), @JSON_KEY NVARCHAR(128) )
RETURNS NVARCHAR(4000)
AS 
BEGIN 
/*
env:  SQL Server 2008R2 
功能:自定义函数 F_JSON_VALUE() 功能同 SQL SERVER 2016 的JSON_VALUE() .
缺点:
  (1)不支持子嵌套JSON对象、JSON数组。 
  (2)JSON值里不能有半角逗号、花括号、双引号
  (3)键与冒号之间必须不能空格,即键与冒号必须紧紧靠在一起。
修改日志:
  1) 修正键值之间空格问题
例子:
select DBO.F_json_value('{"name":"张三","id":20,"date":"2026-07-30"}','$.id') as [ID],
DBO.F_json_value('{"name": "张三" ,"id": "20","date":"2026-07-30"}','$.name') as [NAME],
DBO.F_json_value('{"name":"张三","id":"20","date":"2026-07-30"}','$.date') as [DATE],
DBO.F_json_value('{"name":"张三","id":"20","date":"2026-07-30","iserror":true }','$.iserror') as [IsError]



*/
  declare @result nvarchar(4000);
  declare @key_start int; /* json_key 位置 */    
  declare @key_end int; /* json_key 结束位置 */  
  declare @value_start int;  /* JSON_VALUE 起始位置 */   
  declare @value_end int;  /* JSON_VALUE 结束位置 */      
  declare @key_start_pos int; /* json_key 位置值 */    
  declare @key_end_pos int; /* json_key 结束位置值 */  
  declare @value_start_pos int;  /* JSON_VALUE 起始位置值 */   
  declare @value_end_pos int;  /* JSON_VALUE 结束位置值 */     
  declare @key nvarchar(128); /* 拼出 JSON_KEY 标准表达式 */    
  declare @key_length int; /* 拼出 JSON_KEY 标准表达式 的字符长度 */    
  declare @json_value nvarchar(400), @value_temp nvarchar(500);     
  declare @quot_start_pos int ; /* 双引号起始位置  */   
  declare @quot_end_pos int ; /* 双引号结束位置  */     
  declare @value_length int,
          @delimiter nvarchar(10) = nchar(44), /* 分隔符,JSON键值对 以逗号(,)为分隔符 */
		  @separator nvarchar(10) = nchar(58) , /* 键与值之间的分隔符,以冒号(:)为分隔符  */
		  @delimiter_pos int ,
		  @separator_pos int,
		  @value nvarchar(4000);   

	SET @json_object =  replace (@json_object,'\"','&CHAR(34)'); -- 转义字符
	SET @json_object =  replace (@json_object,'\,','&CHAR(44)'); -- 转义字符
	SET @json_object =  replace (@json_object,'\}','&CHAR(125)'); -- 转义字符
	
   /* 去掉@JSON_KEY前面的 美元符号($.), 并格式化为( "KEY": )完整键 */  
 -- set @key =N'"'+ SUBSTRING(@json_key,3,len(@json_key)) + N'":';  
  set @key =N'"'+ replace(@json_key,N'$.',N'') + N'":';  
  set @key_length = LEN(@key);    
  set @key_start = CHARINDEX(@key,@json_object,1) ;  
  
  set @value_end = CHARINDEX( ',',@json_object,@key_start ) - (@key_start + @key_length)  
  
  if @value_end <0     
   if charIndex('}',@json_object,1) > 0
    set @value_end = CHARINDEX( '}',@json_object,@key_start ) - (@key_start + @key_length)  ;   
   else
    set @value_end = len(@json_object) ;

  if @value_end >0 and @key_start>0      
    set @json_value = SUBSTRING(@json_object,@key_start + @key_length ,@value_end );    
      
  if ltrim(isnull(@json_value,N''))<>N''    
  begin   
	  IF CHARINDEX(NCHAR(34),@json_value,1) >0 
	  BEGIN 
		--set @json_value = REPLACE(@json_value,'"','"');    
		--­要处理双引号
		set @value_length = LEN( @json_value);  
		set @quot_start_pos = CHARINDEX(NCHAR(34),@json_value,1);   
		--set @quot_end_pos =  CHARINDEX(NCHAR(34),reverse(@json_value),1);    
    
		set @value_temp = SUBSTRING(@json_value, @quot_start_pos+1, @value_length  );  
		set @quot_end_pos =  CHARINDEX(NCHAR(34),reverse(RTRIM(@value_temp)),1);   
		set @value_temp = SUBSTRING(@value_temp, 1, len(@value_temp) - @quot_end_pos );
	  END ;
	  ELSE
	  BEGIN
		set @value_temp = @json_value ;
	  END; 
  end;
  else
  begin
    set @value_temp = @json_value ;
  end ;  

    SET @value_temp =  replace (@value_temp ,'&CHAR(34)','\"');  -- 转义字符
	SET @value_temp =  replace (@value_temp ,'&CHAR(44)','\,');  -- 转义字符
	SET @value_temp =  replace (@value_temp ,'&CHAR(125)','\}'); -- 转义字符
 -- set @result = @json_value;
   SET @result = @value_temp;
   RETURN(@result );
END ;

-- 例子:{"name":"张三","id":20,"date":"2026-07-30"}
go

select json_value('{"name": "张三","id":20,"date":"2026-07-30"
  ,"scope":[{"english":"60","chinese":"80"},{"english":"68","chinese":"83"}]}','$.id') as [ID],
  json_value('{"name": "张三","id":20,"date":"2026-07-30"}','$.name') as [NAME]
go

select DBO.F_json_value('{"name":"张三","id":20,"date":"2026-07-30"}','$.id') as [ID],
DBO.F_json_value('{"name": "张三" ,"id": "20","date":"2026-07-30"}','$.name') as [NAME],
DBO.F_json_value('{"name":"张三","id":"20","date":"2026-07-30"}','$.date') as [DATE],
DBO.F_json_value('{"name":"张三","id":"20","date":"2026-07-30","iserror":true }','$.iserror') as [IsError]

  

 

效果图:

image

 

posted @ 2026-07-09 06:38  samrv  阅读(4)  评论(0)    收藏  举报