SQL Server选择JSON函数
我想将SELECT语句的结果作为JSON对象输出 我希望这是一个函数,而不是一个存储过程 例如,下表列出了用户SQL Server选择JSON函数,sql,xml,json,tsql,xquery,Sql,Xml,Json,Tsql,Xquery,我想将SELECT语句的结果作为JSON对象输出 我希望这是一个函数,而不是一个存储过程 例如,下表列出了用户 id name active 1 Bob Jones 1 2 John Smith 0 将按如下方式返回: [{"id":1,"name":"Bob Jones","active":1},{"id":2,"name":"John Smith","active":0}] 提前感谢。从SQL Server 2016开始,您可以使用json: 对
id name active
1 Bob Jones 1
2 John Smith 0
将按如下方式返回:
[{"id":1,"name":"Bob Jones","active":1},{"id":2,"name":"John Smith","active":0}]
提前感谢。从SQL Server 2016开始,您可以使用json: 对于较旧版本的SQL Server,您可以将其用于xml路径,例如: 输出:
[{"id":1,"name":"Bob Jones","active":1},{"id":2,"name":"John Smith","active":0}]
首先,我要感谢Kirill Polishchuk提供的基本代码示例。。。谢谢大家! 我接受了这一点,然后构建了一个过程来完成我需要它做的事情,即根据我想要的任何结果集(即SQL Server中的表对象不可变)为我提供JSON输出 理想情况下,我希望这是一个函数,但是由于在函数中可以做什么的限制,该部分将不得不等待。。。也许是 是的,注册一个扩展过程CLR肯定更容易,但我想暂时避免这样做 PS:对于临时表,只需输入'tempdb..tablename' 这是:
/*
Author: Goran Biljetina
Create date: 03/13/2013
Description: consume a table object (not table var), output it as JSON Properties string
*/
/*
--> example run
-- EXEC dbo.JSONreturn @tblObjNameFQ='[database].[schema].[object_name_table]';
*/
CREATE PROCEDURE dbo.JSONreturn
(
@committedRead bit = 0 --> if 1 then committed else uncommitted read
,@debugmode bit = 0 --> if 1 display certain outputs
,@tblObjNameFQ varchar(128) --> fully qualified table object name, i.e. db.schema.object_name
,@stringJSON nvarchar(max) = null OUTPUT
)
AS
BEGIN
if @committedRead=0
begin
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; --> evaluate if necessary in test phase
end
else if @committedRead=1
begin
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
end
SET NOCOUNT ON;
----------------------------------------------------------------------------------------------------------
if (PATINDEX('%[\.]%',@tblObjNameFQ)<1 AND patindex('%#%',@tblObjNameFQ)<1) OR LEN(@tblObjNameFQ)>(3*128)
begin
PRINT 'table (object) name not fully qualified or invalid!'
RETURN -1
end
declare
@objname varchar(128)
,@dbname varchar(128)
,@schema varchar(128)
,@maxColNum int
,@inc int
,@dqsl_misc varchar(max)
,@dsql_wrapper varchar(max)
,@dsql_what varchar(max)
,@dsql_where varchar(max)
,@dsql_complete varchar(max)
create table #maxColNum (column_id int)
create table #ColPrep (colString varchar(max), column_id int)
create table #JSONoutput (string nvarchar(max))
if patindex('%#%',@tblObjNameFQ)>0
begin
set @objname = (PARSENAME(@tblObjNameFQ,1))
set @dbname = 'tempdb'
end
else if patindex('%#%',@tblObjNameFQ)<1
begin
set @dbname = SUBSTRING(@tblObjNameFQ,1,PATINDEX('%[\.]%',@tblObjNameFQ)-1)
set @objname = convert(varchar,(PARSENAME(@tblObjNameFQ,1)))
set @schema = convert(varchar,(PARSENAME(@tblObjNameFQ,2)))
end
--select @objname[@objname], @dbname[@dbname], @schema[@schema]
--select @dbname+'.'+@schema+'.'+@objname
set @dqsl_misc =
'
select max(column_id)
from '+@dbname+'.sys.columns
where object_id =
(select object_id from '+@dbname+'.sys.objects where type = ''U'' and name like ''%'+@objname+'%'')
'
insert into #maxColNum
exec(@dqsl_misc)
set @maxColNum = (select column_id from #maxColNum)
set @dsql_what = ''
set @dsql_wrapper =
'
select ''['' + STUFF((
select
'',{''+<<REPLACE>>
+''}''
'
set @dsql_where =
'
from '+@dbname+'.'+case when @schema is null then '' else @schema end+'.'+@objname+' t1
for xml path(''''), type
).value(''.'', ''varchar(max)''), 1, 1, '''') + '']''
'
set @dqsl_misc =
'
select ''"''+sysc.name+''": ''
+case
when syst.name like ''%time%'' or syst.collationid is not null then ''"''''+cast(''+sysc.name+'' as varchar(max))+''''",''
when syst.name = ''bit'' then ''''''+cast((case when ''+sysc.name+''=1 then ''''true'''' else ''''false'''' end) as varchar(max))+'''',''
else ''''''+cast(''+sysc.name+'' as varchar(max))+'''',''
end as colString, sysc.column_id
from '+@dbname+'.sys.columns sysc
join '+@dbname+'.sys.systypes syst
on sysc.system_type_id = syst.xtype and syst.xtype <> 240 and syst.name <> ''sysname''
where object_id = (select object_id from '+@dbname+'.sys.objects where type = ''U'' and name like ''%'+@objname+'%'')
order by sysc.column_id
'
insert into #ColPrep
exec(@dqsl_misc)
set @inc = (select MIN(column_id) from #ColPrep)
while @inc<=@maxColNum
begin
set @dsql_what = @dsql_what+(select case
when @inc = @maxColNum then replace(colString,',','')
else colString end
from #ColPrep where column_id = @inc)
set @inc=@inc+1
IF @inc>@maxColNum
set @dsql_what = ''''+@dsql_what+''''
IF @inc>@maxColNum
BREAK
ELSE
CONTINUE
end
set @dsql_complete = REPLACE(@dsql_wrapper,'<<REPLACE>>',@dsql_what)+@dsql_where
insert into #JSONoutput
exec(@dsql_complete)
SET @stringJSON = (Select string from #JSONoutput)
----------------------------------------------------------------------------------------------------------
END
只是为了用最新的技术变化来改进答案。使用sql server 2016
select id, name ,active
from tableName
FOR JSON AUTO
这实际上不适合只使用SQL查询。使用数据库前面的某种程序进行操作更有意义。您使用什么编程语言来显示此数据。有一个使用CLR函数将XML响应解析为JSON的示例。我不知道您是否能在纯t-SQL中找到可行的解决方案。而且。。。到目前为止你试过什么?这看起来更像是一个出价而不是一个问题……我将JSON插入到一个表中,然后使用JSON将其输出。问题是,为什么我不构建JSON服务器端,它包含运行storeprocedure时创建的数据。但这是一个存储过程,我不喜欢你在这里所做的。但表格的内容可能会发生变化。有一次它可能是id、name、active。还有一次,可能是身份证、姓名、电子邮件、日期等…@sparkyfied:我认为你帮不上忙。如果您正在转储到XML,并且内容发生了更改,那么您也会遇到同样的问题。@哎呀,在输出列名和值的列的循环中是否可以这样做,而不需要代码片段,只是想知道它是否是possible@sparkyfied当前位置我相信这是可能的,但我看不出有什么好处。也许我没有领会你的意图。@Eitanmg,如果你使用json,那么你就不需要逃避,如果你使用xml,那么你就需要逃避。我忘了补充一下,是的,我看到了一些错误和不一致。。。但我很快就搞定了,但我只是想说,是的,我知道很不错的!我知道你知道,但它不处理datetime字段,但这没关系。这非常有用。@matadur据我所知,JSON支持是在2016年才添加的,2014年是否有一些更新允许它?可能是在Management Studio的更新中添加的。我有SQL Server 2014和Management Studio 12.0.2000.8,JSON的版本也能正常工作。我的错误是——实际上我测试的是SQL Server 2016;这只是2014年的Mgmt工作室。
/*
Author: Goran Biljetina
Create date: 03/13/2013
Description: consume a table object (not table var), output it as JSON Properties string
*/
/*
--> example run
-- EXEC dbo.JSONreturn @tblObjNameFQ='[database].[schema].[object_name_table]';
*/
CREATE PROCEDURE dbo.JSONreturn
(
@committedRead bit = 0 --> if 1 then committed else uncommitted read
,@debugmode bit = 0 --> if 1 display certain outputs
,@tblObjNameFQ varchar(128) --> fully qualified table object name, i.e. db.schema.object_name
,@stringJSON nvarchar(max) = null OUTPUT
)
AS
BEGIN
if @committedRead=0
begin
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; --> evaluate if necessary in test phase
end
else if @committedRead=1
begin
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
end
SET NOCOUNT ON;
----------------------------------------------------------------------------------------------------------
if (PATINDEX('%[\.]%',@tblObjNameFQ)<1 AND patindex('%#%',@tblObjNameFQ)<1) OR LEN(@tblObjNameFQ)>(3*128)
begin
PRINT 'table (object) name not fully qualified or invalid!'
RETURN -1
end
declare
@objname varchar(128)
,@dbname varchar(128)
,@schema varchar(128)
,@maxColNum int
,@inc int
,@dqsl_misc varchar(max)
,@dsql_wrapper varchar(max)
,@dsql_what varchar(max)
,@dsql_where varchar(max)
,@dsql_complete varchar(max)
create table #maxColNum (column_id int)
create table #ColPrep (colString varchar(max), column_id int)
create table #JSONoutput (string nvarchar(max))
if patindex('%#%',@tblObjNameFQ)>0
begin
set @objname = (PARSENAME(@tblObjNameFQ,1))
set @dbname = 'tempdb'
end
else if patindex('%#%',@tblObjNameFQ)<1
begin
set @dbname = SUBSTRING(@tblObjNameFQ,1,PATINDEX('%[\.]%',@tblObjNameFQ)-1)
set @objname = convert(varchar,(PARSENAME(@tblObjNameFQ,1)))
set @schema = convert(varchar,(PARSENAME(@tblObjNameFQ,2)))
end
--select @objname[@objname], @dbname[@dbname], @schema[@schema]
--select @dbname+'.'+@schema+'.'+@objname
set @dqsl_misc =
'
select max(column_id)
from '+@dbname+'.sys.columns
where object_id =
(select object_id from '+@dbname+'.sys.objects where type = ''U'' and name like ''%'+@objname+'%'')
'
insert into #maxColNum
exec(@dqsl_misc)
set @maxColNum = (select column_id from #maxColNum)
set @dsql_what = ''
set @dsql_wrapper =
'
select ''['' + STUFF((
select
'',{''+<<REPLACE>>
+''}''
'
set @dsql_where =
'
from '+@dbname+'.'+case when @schema is null then '' else @schema end+'.'+@objname+' t1
for xml path(''''), type
).value(''.'', ''varchar(max)''), 1, 1, '''') + '']''
'
set @dqsl_misc =
'
select ''"''+sysc.name+''": ''
+case
when syst.name like ''%time%'' or syst.collationid is not null then ''"''''+cast(''+sysc.name+'' as varchar(max))+''''",''
when syst.name = ''bit'' then ''''''+cast((case when ''+sysc.name+''=1 then ''''true'''' else ''''false'''' end) as varchar(max))+'''',''
else ''''''+cast(''+sysc.name+'' as varchar(max))+'''',''
end as colString, sysc.column_id
from '+@dbname+'.sys.columns sysc
join '+@dbname+'.sys.systypes syst
on sysc.system_type_id = syst.xtype and syst.xtype <> 240 and syst.name <> ''sysname''
where object_id = (select object_id from '+@dbname+'.sys.objects where type = ''U'' and name like ''%'+@objname+'%'')
order by sysc.column_id
'
insert into #ColPrep
exec(@dqsl_misc)
set @inc = (select MIN(column_id) from #ColPrep)
while @inc<=@maxColNum
begin
set @dsql_what = @dsql_what+(select case
when @inc = @maxColNum then replace(colString,',','')
else colString end
from #ColPrep where column_id = @inc)
set @inc=@inc+1
IF @inc>@maxColNum
set @dsql_what = ''''+@dsql_what+''''
IF @inc>@maxColNum
BREAK
ELSE
CONTINUE
end
set @dsql_complete = REPLACE(@dsql_wrapper,'<<REPLACE>>',@dsql_what)+@dsql_where
insert into #JSONoutput
exec(@dsql_complete)
SET @stringJSON = (Select string from #JSONoutput)
----------------------------------------------------------------------------------------------------------
END
select id, name ,active
from tableName
FOR JSON AUTO