SQL Server 2016 中存储过程中的 OPENJSON 语法
Posted
技术标签:
【中文标题】SQL Server 2016 中存储过程中的 OPENJSON 语法【英文标题】:OPENJSON syntax in a stored procedure in SQL Server 2016 【发布时间】:2019-08-26 11:39:50 【问题描述】:我正在关注此页面上的最后一个示例https://www.sqlservercentral.com/forums/topic/using-msxml2-serverxmlhttp-within-stored-procedure-to-grab-source-of-html-page-and-save-to-table。
它提取数据并将其加载到表中。我觉得我在最后一步的语法是错误的。代码提取数据,但我的OPENJSON
错误,因此没有将数据放入表中。任何帮助表示赞赏。
DECLARE @Object AS INT;
DECLARE @hr INT
DECLARE @json AS TABLE (Json_Table NVARCHAR(MAX))
DECLARE @pmidList NVARCHAR(MAX)
SET @PMIDLIST = '17784783,19505939,30166592'
DECLARE @url NVARCHAR(MAX)
SET @url = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&retmode=json&id='+ @pmidList
EXEC @hr = sp_OACreate 'MSXML2.ServerXMLHTTP.6.0', @Object OUT;
IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
EXEC @hr = sp_OAMethod @Object, 'open', NULL, 'get',
@url OUT,
'false'
IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
EXEC @hr = sp_OAMethod @Object, 'send'
IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
EXEC @hr = sp_OAMethod @Object, 'responseText', @json OUTPUT
IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
INSERT INTO @json (Json_Table)
EXEC sp_OAGetProperty @Object, 'responseText'
-- select the JSON string
SELECT * FROM @json
-- Parse the JSON string
SELECT *
FROM OPENJSON((SELECT * FROM @json), N'$.result')
WITH (
[uid] NVARCHAR(MAX) N'$.uids.uid',
[title] NVARCHAR(MAX) N'$.uids.title' ,
[sortpubdate] NVARCHAR(MAX) N'$.uids.sortpubdate',
[epubdate] NVARCHAR(MAX) N'$.uids.epubdate'
)
EXEC sp_OADestroy @Object
返回的数据是:
"header": "type": "esummary",version": "0.3","result": "uids": ["17784783","19505939","30166592"],"17784783": "uid": "17784783","pubdate": "2007 Aug","epubdate": "2007 Jul 20", "source": "PLoS Comput Biol","title": "Pathway... ",
我想知道是否可以解析
添加编辑数据
DECLARE @json NVARCHAR(MAX)
SET @json = '
"header":
"type": "esummary",
"version": "0.3"
,
"result":
"uids": [
"17784783",
"19505939",
"30166592"
],
"17784783":
"uid": "17784783",
"pubdate": "2007 Aug",
"epubdate": "2007 Jul 20",
"source": "PLoS Comput Biol",
"sortpubdate": "2007/08/01 00:00"
,
"19505939":
"uid": "19505939",
"pubdate": "2009 Aug 1",
"epubdate": "2009 Jun 8",
"source": "Bioinformatics",
"sortpubdate": "2009/08/01 00:00"
,
"30166592":
"uid": "30166592",
"pubdate": "2019 Jan",
"epubdate": "2018 Aug 30",
"source": "Oncogene",
"sortpubdate": "2019/01/01 00:00"
'
print @json
SELECT * FROM OPENJSON((select * from @json), N'$.result')
WITH (
[uid] nvarchar(max) N'$.uids.uid' ,
[sortpubdate] nvarchar(max) N'$.uids.sortpubdate',
[epubdate] nvarchar(max) N'$.uids.epubdate'
)
需要结果
17784783 2007/08/01 00:00 2007 Jul 20
19505939 2009/08/01 00:00 2009 Jun 8
30166592 2019/01/01 00:00 2018 Aug 30
【问题讨论】:
如果你问的是你对openjson
的使用情况,为什么我们需要在此之前查看所有代码?如果您可以edit您的问题将示例数据包含为 DDL+DML 和预期结果,那将更容易回答。
我将所有代码放在那里,以便人们可以复制、粘贴和执行到 SQL Studio 中并获得准确的输出。有错吗?
一般来说,不,这没有错。但是,所有这些存储过程都需要我们中的一些人可能没有的权限,而且我不了解大多数其他用户,但是当我想回答一个 SQL 问题时,我通常会先在 rextester 或 dbfiddle 上尝试我的解决方案——然后你出于安全原因,无法在这些服务上运行这些程序。根据经验,如果您的问题可以是自包含的,那么它应该是自包含的。不要将我们发送到互联网来获取数据,只需将其合并到问题本身中即可。
【参考方案1】:
一种方法是使用 openjson
作为 json 字符串,并将其与另一个 openjson
内部数组交叉应用:
SELECT [uid], [sortpubdate], [epubdate]
FROM OPENJSON(@json, N'$.result') As items
CROSS APPLY
-- parse each object in the array
OPENJSON(items.[value])
WITH(
[uid] nvarchar(max) N'$.uid' ,
[sortpubdate] nvarchar(max) N'$.sortpubdate',
[epubdate] nvarchar(max) N'$.epubdate'
) As content
WHERE [key] <> 'uids' -- Get only the relevant content
结果:
uid sortpubdate epubdate
17784783 2007/08/01 00:00 2007 Jul 20
19505939 2009/08/01 00:00 2009 Jun 8
30166592 2019/01/01 00:00 2018 Aug 30
【讨论】:
添加到***.com/questions/57659416/…以上是关于SQL Server 2016 中存储过程中的 OPENJSON 语法的主要内容,如果未能解决你的问题,请参考以下文章
我应该如何使用 sql server 中的存储过程将列名存储在变量中?
如何在 Microsoft SQL Server 2017 上调试存储过程?
在 SQL Server 2016 中调试一个关于存储过程执行的奇怪场景