mysql 动态sql 解析json数据_在SQL 中生成JSON数据

这段时间接手一个数据操作记录的功能,刚拿到手上的时候打算用EF做,后来经过仔细考虑最后还是觉定放弃,最后思考再三决定:

1、以模块为单位分表、列固定(其实可以所有的操作记录都放到同一个表,但是考虑到数据量大的时候查询性能的问题还是分表吧)列:主键ID、引用记录主键ID、操作时间、操作类型、详细信息(里面存储的就是序列化后的值)

2、在客服端解析保存的序列化的值

但是用xml还是用json呢,这有是一个问题,显然用xml在存储过程正很容易就能生成了:SELECT * FROM TABLE FOR XML AUTO 就ok了,

但是用xml的话,在客服端解析就麻烦些了,所以弃用了xml保存,而使用了最爱的json,现在的问题就是写一个通用的存储过程来生成json了,经过我1天多的拼写终于出炉了(其实难度不大,就是拼字符串容易出错)

/*=================获取JSON格式数据

@TableName varchar(100):表名

@ColumnIn nvarchar(100):列名,用于判断,

@ColumnValues nvarchar(max):值'aaa,bbb,ccc',

@Condition NVARCHAR(max):条件(and 1=1)

@Json varchar(max) OUTPUT:生成的JSON数据

@Limit int =NULL :取前多少条,为null 取所有

@ConvertColumns NVARCHAR(max)=null:要转换的列(目前已经排除为nvarchar(max)的列)

==================================*/

create PROC uspGetJSON(

@TableName varchar(100),

@ColumnIn nvarchar(100)='',

@ColumnValues nvarchar(max),

@Condition NVARCHAR(max)='',

@Json varchar(max) OUTPUT,

@Limit int =NULL,

@ConvertColumns NVARCHAR(max)=null

--@SortColumn nvarchar(100)=null,

--@SortType nvarchar(10)='asc'

)

AS

--if(@SortColumn is null)

--set @SortColumn='LastModifiedDate'

declare @query varchar(max),

@table_schema varchar(max) = null

if(charindex('.', @TableName) > 0 )

begin

set @table_schema = replace(replace( substring(@TableName, 0, charindex('.',@TableName)), '[', ''), ']', '')

set @TableName = replace(replace( substring(@TableName, charindex('.',@TableName) + 1,len(@TableName)), '[', ''), ']', '')

END

IF EXISTS ( SELECT 1 FROM tempdb..sysobjects WHERE id = OBJECT_ID('tempdb..#tmpJsonTable') )

DROP TABLE #tmpJsonTable

CREATE TABLE #tmpJsonTable

(

json NVARCHAR(max) NULL

)

--"dd"

set @query =

'insert into #tmpJsonTable select ' + case when @Limit is not null then 'top ' + cast(@Limit as varchar(32)) + ' ' else '' end + '''{ '' + REVERSE(STUFF(REVERSE(''' +

CAST((SELECT ' "' + column_name + '" : ' +

----处理为null的问题

case WHEN is_nullable = 'YES' then ''' + case when [' + column_name + '] is null then ''null'' else ' +

--处理前缀"

case WHEN data_type='uniqueidentifier'or data_type like '%date%' or data_type like '%char%' or data_type like '%text%' then '''"'' + ' else '' end +

/*类型转换*/

case WHEN data_type like '%date%' then 'convert(varchar(23),[' + column_name + '], 20)+ ''"'''

else 'replace(replace(replace(replace(replace(cast([' + column_name + '] as varchar(max)),''\'',''\\''),''"'',''\"''),char(10),''\n''),char(13),''\n''),char(9),''\t'') ' end +

--处理后缀"

case WHEN data_type='uniqueidentifier' or data_type like '%char%' or data_type like '%text%' then '+ ''"''' else '' end + ' end + '''

ELSE

--处理前缀"

case WHEN data_type='uniqueidentifier' or data_type like '%date%' or data_type like '%char%' or data_type like '%text%' then '"' else '' end + ''' + ' +

/*类型转换*/

case WHEN data_type like '%date%' then 'convert(varchar(23),[' + column_name + '], 20)+ '''

else 'replace(replace(replace(replace(replace(cast([' + column_name + '] as varchar(max)),''\'',''\\''),''"'',''\"''),char(10),''\n''),char(13),''\n''),char(9),''\t'') + ''' end +

--处理后缀"

case WHEN data_type='uniqueidentifier'OR data_type LIKE 'date%' or data_type like '%char%' or data_type like '%text%' then '"' else '' end end + ','

AS [text()]

from information_schema.columns

where table_name = @TableName

and (character_maximum_length IS NULL OR character_maximum_length!=-1)

AND(@ConvertColumns IS NULL OR COLUMN_NAME IN(SELECT MyValues FROM dbo.funSplitArray(@ConvertColumns,',')))

and (@table_schema is null or table_schema = @table_schema) FOR XML PATH('') ) as varchar(max)) +

'''),1,1,'''')) + '' }'' as json from ' + @TableName + ' with(nolock) where ('+@ColumnIn+' in (Select MyValues from dbo.funSplitArray('''+@ColumnValues+''','',''))) '+@Condition--+' ORDER BY '+@SortColumn+' '+@SortType

exec sp_sqlexec @query

--SELECT @query

set @Json =

--'{' + char(10) + char(9) +

--'"recordCount" : ' + Cast((select count(*) from #tmpJsonTable) as varchar(32)) + ',' + char(10) + char(9) +

--'"records" : ' + char(10) + char(9) + char(9) +

'[' + char(10)

+ REVERSE(STUFF(REVERSE(CAST((SELECT char(9) + char(9) + json + ',' + char(10) AS [text()] FROM #tmpJsonTable FOR XML PATH('')) AS varchar(max))),1,2,''))

+ char(10) + char(9) + char(9) + ']'

-- + char(10) + '}'

drop table #tmpJsonTable

--DECLARE @table_name varchar(100)='SalesOrder',

-- @ConvertColumns NVARCHAR(max)='SalesOrderNo,SalesOrderID',

-- @Condition NVARCHAR(max)='',

-- @json varchar(max)

--EXEC GetJSON @table_name=@table_name,@ConvertColumns=@ConvertColumns,@Condition=@Condition,@json=@json OUTPUT

--SELECT @json

调用这个存储过程使用输出参数就可以得到序列化后的json数据了。

至此,就差在客服端解析了。打算写个方法根据传递过来的json对象参数来动态解析,这样 ui页面上也不需要用每个地方都去解析了....

--用到的自定义函数

CREATE function [dbo].[funSplitArray](@aString varchar(max),@pattern varchar(10))

returns @temp table([Sid] [int] IDENTITY (1, 1) NOT NULL ,Myvalues varchar(100))

--实现split功能的函数

--说明:@aString,字符串,如“27,28,29”;@pattern,分隔标志,如“ ,”

--使用select Myvalues FROM my_split(字符串, ',')

as

begin

declare @i int

set @aString=rtrim(ltrim(@aString))

set @i=charindex(@pattern,@aString)

while @i>=1

begin

insert @temp values(left(@aString,@i-1))

set @aString=substring(@aString,@i+1,len(@aString)-@i)

set @i=charindex(@pattern,@aString)

end

if @aString<>''

insert @temp values(@aString)

return

end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值