问题:从MS SQL 2014中的SQL查询生成JSON的最佳解决方案是什么?我创建了一个过程,但是它很慢。
我的例子:
DECLARE @customers xml;
DECLARE @json NVARCHAR(max);
SET @customers = (SELECT * FROM dbo.Customers FOR XML path, root)
EXEC [dbo].[HTTP_JSON] @customers, @json
EXEC [dbo].[HTTP_JSON](@Shopping)
Create PROCEDURE [dbo].[HTTP_JSON]
@parameters xml, @response NVARCHAR(max) OUTPUT
WITH EXEC AS CALLER
AS
set @response = (SELECT Stuff(
(SELECT * from
(SELECT ',
{'+
Stuff((SELECT ',"'+coalesce(b.c.value('local-name(.)', 'NVARCHAR(MAX)'),'')+'":"'+
b.c.value('text()[1]','NVARCHAR(MAX)') +'"'
from x.a.nodes('*') b(c)
for xml path(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)')
,1,1,'')+'}'
from @parameters.nodes('/root/*') x(a)
) JSON(theLine)
for xml path(''),TYPE).value('.','NVARCHAR(MAX)' )
,1,1,''))
GO
只是为了好玩,我根据之前的答案创建了一个标量函数。
除了显而易见的XML参数外,我还添加了两个附加功能:1)包括Header(如下图所示),以及2)ToLower大小写(我更喜欢使用小写的JSON字段名称,该名称链接到类等)。
如果查询不止一个记录,则将返回格式化的数组。
Declare @Table table (ID int,Active bit,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50))
Insert into @Table values
(1,1,'John','Smith','john.smith@email.com'),
(2,0,'Jane','Doe' ,'jane.doe@email.com')
Select A.ID
,A.Last_Name
,A.First_Name
,B.JSON
From @Table A
Cross Apply (Select JSON=[dbo].[udf-Str-JSON](0,1,(Select A.* For XML Raw)) ) B
退货
ID Last_Name First_Name JSON
1 Smith John {"id":"1","active":"1","first_name":"John","last_name":"Smith","email":"john.smith@email.com"}
2 Doe Jane {"id":"2","active":"0","first_name":"Jane","last_name":"Doe","email":"jane.doe@email.com"}
甚至更简单
Select JSON=[dbo].[udf-Str-JSON](0,1,(Select * From @Table for XML RAW))
标题打开时返回
{
"status": {
"successful": "true",
"timestamp": "2016-10-09 06:08:16 GMT",
"rows": "2"
},
"results": [{
"id": "1",
"active": "1",
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@email.com"
}, {
"id": "2",
"active": "0",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane.doe@email.com"
}]
}
标题关闭时返回
[{
"id": "1",
"active": "1",
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@email.com"
}, {
"id": "2",
"active": "0",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane.doe@email.com"
}]
UDF
ALTER FUNCTION [dbo].[udf-Str-JSON] (@IncludeHead int,@ToLowerCase int,@XML xml)
Returns varchar(max)
AS
Begin
Declare @Head varchar(max) = '',@JSON varchar(max) = ''
; with cteEAV as (Select RowNr=Row_Number() over (Order By (Select NULL))
,Entity = xRow.value('@*[1]','varchar(100)')
,Attribute = xAtt.value('local-name(.)','varchar(100)')
,Value = xAtt.value('.','varchar(max)')
From @XML.nodes('/row') As R(xRow)
Cross Apply R.xRow.nodes('./@*') As A(xAtt) )
,cteSum as (Select Records=count(Distinct Entity)
,Head = IIF(@IncludeHead=0,IIF(count(Distinct Entity)<=1,'[getResults]','[[getResults]]'),Concat('{"status":{"successful":"true","timestamp":"',Format(GetUTCDate(),'yyyy-MM-dd hh:mm:ss '),'GMT','","rows":"',count(Distinct Entity),'"},"results":[[getResults]]}') )
From cteEAV)
,cteBld as (Select *
,NewRow=IIF(Lag(Entity,1) over (Partition By Entity Order By (Select NULL))=Entity,'',',{')
,EndRow=IIF(Lead(Entity,1) over (Partition By Entity Order By (Select NULL))=Entity,',','}')
,JSON=Concat('"',IIF(@ToLowerCase=1,Lower(Attribute),Attribute),'":','"',Value,'"')
From cteEAV )
Select @JSON = @JSON+NewRow+JSON+EndRow,@Head = Head From cteBld, cteSum
Return Replace(@Head,'[getResults]',Stuff(@JSON,1,1,''))
End
-- Parameter 1: @IncludeHead 1/0
-- Parameter 2: @ToLowerCase 1/0 (converts field name to lowercase
-- Parameter 3: (Select * From ... for XML RAW)
**编辑-修正错字
问题内容: 我想知道是否可以限制SQL请求的结果? 例如,最多只返回以下内容的50行: 谢谢。 问题答案: 是的,这是可能的。这在数据库引擎之间有所不同。 Postgres: SQL Server: …
问题内容: 实际上,我有一个SQL查询可以很好地与数据库一起运行。但是,我的问题是我想在查询中编写该查询。 我的SQL查询是 我希望它由hibernate模板执行。 如何将其转换为查询? 问题答案: 如果要使用查询,则下面是hibernate查询的示例,但是在您的情况下,我们需要映射文件以查看实体之间的关联。希望下面的查询对您有所帮助。 要么
问题内容: 我问这个问题有点傻,因为我似乎是世界上唯一一个不了解这个问题的人,但是无论如何,这都是可行的。我将以Python为例。当我使用原始SQL查询(通常使用ORM)时,我会使用参数化,例如使用SQLite的以下示例: 方法A: 我知道这可行,我知道这是通常推荐的方式。SQL注入易受攻击的方式可以执行以下操作: 方法B: 到目前为止,我可以告诉我了解SQL注入,如本Wikipedia文章中所述
问题内容: 我非常确定我们不能将LIMIT子句用于我想做的事情-因此想确定是否还有其他方法可以实现此目的。 我有一个表,其中捕获了哪个用户访问了哪个商店。每次用户访问商店时,都会在此表中插入一行。 一些领域是 shopping_id(primary key) store_id user_id 现在,我想要的是-对于给定的一组商店,找到访问该商店的最大次数的前5位用户。 我可以一次在1个商店中进行以
我写了一个代码来管理一个咖啡馆,所以在框架中我添加了一个JTable,每次我从JComboBox中选择一个项目,它都应该显示在JTable中。为此,我添加了一个按钮,对于它的操作,我确保每次单击它时,它都将从JComboBox中单击的项存储在数据库中,然后将从数据库中获取的项存储在JTable中。但问题是JTable有两列,而JComboBox中的选择只有一列。因此,另一列必须从其他数据库调用,这
我变得非常困惑,我试图通过laravels query builder运行一个应该可以工作的查询,但它会抛出奇怪的错误。