如何将多个 JSON 行插入到 T-SQL table
How to insert multiple JSON rows into a T-SQL table
我正在尝试将以下 JSON 文档插入到 T-SQL:
{
"GLDETAIL": {
"RECORDNO": "264378-1756289-919567--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264378-1756290-919568--accrual",
"BATCH_DATE": "02/01/2022"
}
}
,
{
"GLDETAIL": {
"RECORDNO": "264379-1756291-919569--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264379-1756292-919570--accrual",
"BATCH_DATE": "02/01/2022"
}
}
,
这是我试图修复的 T-SQL 存储过程,但它只插入了一行而不是四行。
CREATE PROCEDURE [dbo].[InsertPerfCounterData1]
@json NVARCHAR(max)
AS
BEGIN
INSERT INTO dbo.PerfCounter2 (
[RECORDNO]
,[BATCH_DATE]
)
SELECT
RECORDNO,
BATCH_DATE
FROM OPENJSON(@json)
CROSS APPLY OPENJSON (@json)
WITH (
RECORDNO VARCHAR(MAX) '$.GLDETAIL.RECORDNO',
BATCH_DATE DATETIME2(7) '$.GLDETAIL.BATCH_DATE'
) AS jsonValues
END
这是 table.
中的结果
RECORDNO BATCH_DATE
264378-1756289-919567--accrual 2022-02-01 00:00:00.0000000
我认为这与“CROSS APPLY and OPENJSON”的位置有关,但我不确定如何解决它。
更新:
我在应用 Larnu 在下面提供的新 SQL 脚本后遇到此错误:
System.Data.SqlClient.SqlException
HResult=0x80131904
Message=JSON text is not properly formatted. Unexpected character ']'
is found at position 501.
Source=Core .Net SqlClient Data Provider
这是 C# 代码:
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sprocname, conn))
{
// Set command object as a stored procedure
cmd.CommandType = CommandType.StoredProcedure;
// Add parameter that will be passed to stored procedure
cmd.Parameters.Add(new SqlParameter(paramName, paramValue));
cmd.ExecuteReader();
}
}
这是因为您的 JSON 有多个根节点,所以 SQL 服务器只获取第一个。我们可以通过以下方式看到这一点:
DECLARE @JSON nvarchar(MAX) = N'{
"GLDETAIL": {
"RECORDNO": "264378-1756289-919567--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264378-1756290-919568--accrual",
"BATCH_DATE": "02/01/2022"
}
}';
SELECT *
FROM OPENJSON(@JSON)
注意只拾取了一组,对于 GLDETAIL,不是 2。
我们可以通过将数据放入数组中来“解决”这个问题:
DECLARE @JSON nvarchar(MAX) = N'{
"GLDETAIL": {
"RECORDNO": "264378-1756289-919567--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264378-1756290-919568--accrual",
"BATCH_DATE": "02/01/2022"
}
}
,
{
"GLDETAIL": {
"RECORDNO": "264379-1756291-919569--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264379-1756292-919570--accrual",
"BATCH_DATE": "02/01/2022"
}
}';
SELECT GLD.RECORDNO,
GLD.BATCH_DATE
FROM OPENJSON(CONCAT('[',@JSON,']')) OJ
CROSS APPLY OPENJSON(OJ.[value],'$.GLDETAIL')
WITH (RECORDNO varchar(30),--USe an appropriate length, not MAX
BATCH_DATE date) GLD;
在编辑您的 post 之前,将 Json 放入“[ ]”即可解决问题。
而且我认为你甚至不需要 CROSS APPLY OPENJSON (@JSON)
。查询将是这样的:
DECLARE @JSON nvarchar(MAX) = N'
{"GLDETAIL": {"RECORDNO": "264378-1756289-919567--accrual", "BATCH_DATE": "02/01/2022"}},
{"GLDETAIL": {"RECORDNO": "264378-1756290-919568--accrual", "BATCH_DATE": "02/01/2022"}},
{"GLDETAIL": {"RECORDNO": "264379-1756291-919569--accrual", "BATCH_DATE": "02/01/2022"}},
{"GLDETAIL": {"RECORDNO": "264379-1756292-919570--accrual", "BATCH_DATE": "02/01/2022"}}';
INSERT INTO dbo.PerfCounter2 (
[RECORDNO]
,[BATCH_DATE]
)
SELECT RECORDNO, BATCH_DATE
FROM OPENJSON((CONCAT('[',@JSON,']')))
--CROSS APPLY OPENJSON (@JSON)
WITH (
RECORDNO VARCHAR(30) '$.GLDETAIL.RECORDNO', --Use also an appropriate length, not MAX
BATCH_DATE DATETIME2(7) '$.GLDETAIL.BATCH_DATE'
) AS jsonValues
我正在尝试将以下 JSON 文档插入到 T-SQL:
{
"GLDETAIL": {
"RECORDNO": "264378-1756289-919567--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264378-1756290-919568--accrual",
"BATCH_DATE": "02/01/2022"
}
}
,
{
"GLDETAIL": {
"RECORDNO": "264379-1756291-919569--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264379-1756292-919570--accrual",
"BATCH_DATE": "02/01/2022"
}
}
,
这是我试图修复的 T-SQL 存储过程,但它只插入了一行而不是四行。
CREATE PROCEDURE [dbo].[InsertPerfCounterData1]
@json NVARCHAR(max)
AS
BEGIN
INSERT INTO dbo.PerfCounter2 (
[RECORDNO]
,[BATCH_DATE]
)
SELECT
RECORDNO,
BATCH_DATE
FROM OPENJSON(@json)
CROSS APPLY OPENJSON (@json)
WITH (
RECORDNO VARCHAR(MAX) '$.GLDETAIL.RECORDNO',
BATCH_DATE DATETIME2(7) '$.GLDETAIL.BATCH_DATE'
) AS jsonValues
END
这是 table.
中的结果RECORDNO BATCH_DATE
264378-1756289-919567--accrual 2022-02-01 00:00:00.0000000
我认为这与“CROSS APPLY and OPENJSON”的位置有关,但我不确定如何解决它。
更新:
我在应用 Larnu 在下面提供的新 SQL 脚本后遇到此错误:
System.Data.SqlClient.SqlException
HResult=0x80131904
Message=JSON text is not properly formatted. Unexpected character ']'
is found at position 501.
Source=Core .Net SqlClient Data Provider
这是 C# 代码:
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sprocname, conn))
{
// Set command object as a stored procedure
cmd.CommandType = CommandType.StoredProcedure;
// Add parameter that will be passed to stored procedure
cmd.Parameters.Add(new SqlParameter(paramName, paramValue));
cmd.ExecuteReader();
}
}
这是因为您的 JSON 有多个根节点,所以 SQL 服务器只获取第一个。我们可以通过以下方式看到这一点:
DECLARE @JSON nvarchar(MAX) = N'{
"GLDETAIL": {
"RECORDNO": "264378-1756289-919567--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264378-1756290-919568--accrual",
"BATCH_DATE": "02/01/2022"
}
}';
SELECT *
FROM OPENJSON(@JSON)
注意只拾取了一组,对于 GLDETAIL,不是 2。
我们可以通过将数据放入数组中来“解决”这个问题:
DECLARE @JSON nvarchar(MAX) = N'{
"GLDETAIL": {
"RECORDNO": "264378-1756289-919567--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264378-1756290-919568--accrual",
"BATCH_DATE": "02/01/2022"
}
}
,
{
"GLDETAIL": {
"RECORDNO": "264379-1756291-919569--accrual",
"BATCH_DATE": "02/01/2022"
}
},
{
"GLDETAIL": {
"RECORDNO": "264379-1756292-919570--accrual",
"BATCH_DATE": "02/01/2022"
}
}';
SELECT GLD.RECORDNO,
GLD.BATCH_DATE
FROM OPENJSON(CONCAT('[',@JSON,']')) OJ
CROSS APPLY OPENJSON(OJ.[value],'$.GLDETAIL')
WITH (RECORDNO varchar(30),--USe an appropriate length, not MAX
BATCH_DATE date) GLD;
在编辑您的 post 之前,将 Json 放入“[ ]”即可解决问题。
而且我认为你甚至不需要 CROSS APPLY OPENJSON (@JSON)
。查询将是这样的:
DECLARE @JSON nvarchar(MAX) = N'
{"GLDETAIL": {"RECORDNO": "264378-1756289-919567--accrual", "BATCH_DATE": "02/01/2022"}},
{"GLDETAIL": {"RECORDNO": "264378-1756290-919568--accrual", "BATCH_DATE": "02/01/2022"}},
{"GLDETAIL": {"RECORDNO": "264379-1756291-919569--accrual", "BATCH_DATE": "02/01/2022"}},
{"GLDETAIL": {"RECORDNO": "264379-1756292-919570--accrual", "BATCH_DATE": "02/01/2022"}}';
INSERT INTO dbo.PerfCounter2 (
[RECORDNO]
,[BATCH_DATE]
)
SELECT RECORDNO, BATCH_DATE
FROM OPENJSON((CONCAT('[',@JSON,']')))
--CROSS APPLY OPENJSON (@JSON)
WITH (
RECORDNO VARCHAR(30) '$.GLDETAIL.RECORDNO', --Use also an appropriate length, not MAX
BATCH_DATE DATETIME2(7) '$.GLDETAIL.BATCH_DATE'
) AS jsonValues