'How to insert multiple JSON rows into a T-SQL table
I am trying to insert following JSON document into 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"
    }
  }
,
This is T-SQL stored procedure that I was trying to fix, but only it inserted one row instead of four.
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
This is result inside table.
RECORDNO                        BATCH_DATE
264378-1756289-919567--accrual  2022-02-01 00:00:00.0000000
I believe it is something to do with where it has "CROSS APPLY and OPENJSON", but I am not sure how to fix it.
Update:
I got this error after I applied the new SQL script that Larnu provided below:
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
This is C# code:
     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();
            }
        }
							
						Solution 1:[1]
This is because your JSON has multiple root nodes, and so SQL Server is only picking up the first. We can see this with the following:
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)
Notice only one set is picked up, for GLDETAIL, not 2.
We can "fix" this by making the data inside an array:
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;
    					Solution 2:[2]
Before editing your post, the problem would solved by putting the Json in "[ ]".
And I think you even  don't need  CROSS APPLY OPENJSON (@JSON). The Query will be like this:
    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
    					Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | Larnu | 
| Solution 2 | 


