Arrays 在SQL Server中遍历对象数组并获取错误:JSON文本格式不正确
我试图在JSON object@files中循环遍历一个对象数组, 并将数组中的每个对象插入到表中,但我得到以下错误: JSON文本格式不正确。在位置0处发现意外字符“.” JSON使用JSONLint是有效的,所以我知道它不是我声明的对象,除非我错了。选择错误时,会在OPENJSON WITH语句中突出显示此错误: 文件名NVARCHAR100'$.fileName' 试试这个:Arrays 在SQL Server中遍历对象数组并获取错误:JSON文本格式不正确,arrays,json,sql-server,tsql,ssms,Arrays,Json,Sql Server,Tsql,Ssms,我试图在JSON object@files中循环遍历一个对象数组, 并将数组中的每个对象插入到表中,但我得到以下错误: JSON文本格式不正确。在位置0处发现意外字符“.” JSON使用JSONLint是有效的,所以我知道它不是我声明的对象,除非我错了。选择错误时,会在OPENJSON WITH语句中突出显示此错误: 文件名NVARCHAR100'$.fileName' 试试这个: ALTER PROCEDURE files_uploadAll @document_id INT OUTPUT,
ALTER PROCEDURE files_uploadAll
@document_id INT OUTPUT,
@files NVARCHAR(MAX)
AS
BEGIN
INSERT INTO documents
(note_id, document_title, file_name, file_extension, mime_type, document_type_cd, user_id, url)
SELECT note_id, document_title, file_name, file_extension, mime_type, document_type_cd, user_id, url
FROM OPENJSON(@files)
WITH (
note_id INT '$.noteId',
document_title NVARCHAR(100) '$.documentTitle',
file_name NVARCHAR(100) '$.fileName',
file_extension NVARCHAR(25) '$.fileExtension',
mime_type NVARCHAR(50) '$.mimeType',
document_type_cd CHAR(5) '$.documentTypeCd',
user_id int '$.userId',
url NVARCHAR(1000) '$.url'
)
SET @document_id=SCOPE_IDENTITY()
END
执行:
DECLARE @d INT
DECLARE @f NVARCHAR(MAX) = N'[
{
"noteId": 1,
"documentTitle": "doc1",
"fileName": "doc1.pdf",
"fileExtension": "pdf",
"mimeType": "application/pdf",
"documentTypeCd": "MSA",
"userId": 1,
"url": "http://www.url.com"
},
{
"noteId": 2,
"documentTitle": "doc2",
"fileName": "doc2.doc",
"fileExtension": "doc",
"mimeType": "application/msword",
"documentTypeCd": "MSA",
"userId": 1,
"url": "http://www.url.com"
}
]';
EXECUTE files_uploadAll @files=@f, @document_id=@d OUTPUT
这里,如果您注意到我刚刚添加了array作为param&没有循环,我们可以插入具有性能的数据。由于JSON中有根元素,您需要使用根元素调用OPENJSON,如下所示。您现在不会得到错误
不需要任何循环,也不需要更改输入。这可以通过以下查询轻松解决:
SELECT *
FROM OPENJSON(JSON_QUERY(@files,'$.files'))
WITH (
note_id INT '$.noteId',
document_title NVARCHAR(100) '$.documentTitle',
file_name NVARCHAR(100) '$.fileName',
file_extension NVARCHAR(25) '$.fileExtension',
mime_type NVARCHAR(50) '$.mimeType',
document_type_cd CHAR(5) '$.documentTypeCd',
user_id int '$.userId',
url NVARCHAR(1000) '$.url'
);
返回是一个简单的结果集,可用于任何操作:
+---------+----------------+-----------+----------------+--------------------+------------------+---------+--------------------+
| note_id | document_title | file_name | file_extension | mime_type | document_type_cd | user_id | url |
+---------+----------------+-----------+----------------+--------------------+------------------+---------+--------------------+
| 1 | doc1 | doc1.pdf | pdf | application/pdf | MSA | 1 | http://www.url.com |
+---------+----------------+-----------+----------------+--------------------+------------------+---------+--------------------+
| 2 | doc2 | doc2.doc | doc | application/msword | MSA | 1 | http://www.url.com |
+---------+----------------+-----------+----------------+--------------------+------------------+---------+--------------------+
我使用JSON_查询进入$文件。OPENJSON将返回对象数组,而WITH子句将对象转换为命名和类型化列。这是SQL server 2017&compatibility level 130或更高版本吗?您要求他们更改json文件。您必须为他们的json文件提供解决方案。不更改json,而是删除冗余包装,作为一个开发人员,我们知道在应用层删除它更容易、更高效,因为序列化是在一个实体中完成的,该实体具有名为files的文件集合。只需向db发送一个级别,在应用程序级别上什么都不做。若代码无法更改,我可以更改答案,但这样更有效,我必须强烈反对!1在查询级别很容易解决这个问题,请参见我的答案。2通常我们无法更改发送应用程序。3更常见的情况是,我们不想更改发送应用程序。4我们不想混合使用不同风格的数据5和(可能的)现有数据6,如果这个包装是多余的,你不知道。公平地说,这两个都是假设。取决于您的看法,我从ui到代码再到db端到端地工作,因此在调用存储过程中删除冗余包装似乎更具性能,因为从长远来看,我们必须维护混乱,所以需要对obj.files而不是obj.files进行类更改。在进行性能调整时,始终只发送您需要的内容。这非常有效!通过移除包装器,处理数据变得容易得多,并且可以轻松地将其添加到我的表中。谢谢这可能可行,但OPENJSON将返回一个表,这对于根元素来说是相当大的开销。你可能想看看我的答案。最好在这个返回值上使用JSON_查询,然后使用OPENJSON。这对返回结果集很有效,但我需要将数据插入到包含外键的表中,所以我使用了下面的Pranav解决方案。我发现移除包装器不会干扰我将要发送的数据。@hypnagogia您可以直接从此语句一次插入所有内容吗?通常这样的事情是针对一个临时表2-step-import完成的。它确实起了作用,我能够通过使用AJAX调用多路复用将数据插入表中,我发送了一个带有对象数组的请求,并以正确的顺序获取了所有数据。
SELECT *
FROM OPENJSON(JSON_QUERY(@files,'$.files'))
WITH (
note_id INT '$.noteId',
document_title NVARCHAR(100) '$.documentTitle',
file_name NVARCHAR(100) '$.fileName',
file_extension NVARCHAR(25) '$.fileExtension',
mime_type NVARCHAR(50) '$.mimeType',
document_type_cd CHAR(5) '$.documentTypeCd',
user_id int '$.userId',
url NVARCHAR(1000) '$.url'
);
+---------+----------------+-----------+----------------+--------------------+------------------+---------+--------------------+
| note_id | document_title | file_name | file_extension | mime_type | document_type_cd | user_id | url |
+---------+----------------+-----------+----------------+--------------------+------------------+---------+--------------------+
| 1 | doc1 | doc1.pdf | pdf | application/pdf | MSA | 1 | http://www.url.com |
+---------+----------------+-----------+----------------+--------------------+------------------+---------+--------------------+
| 2 | doc2 | doc2.doc | doc | application/msword | MSA | 1 | http://www.url.com |
+---------+----------------+-----------+----------------+--------------------+------------------+---------+--------------------+