简体   繁体   English

如何使用存储过程将多个 JSON 行插入到 T-SQL 表中

[英]How to insert multiple JSON rows into a T-SQL table using a stored procedure

I am trying to insert multiple rows of JSON output into SQL using C#.我正在尝试使用 C# 将多行 JSON output 插入到 SQL 中。

This is C# code that I have:这是我拥有的 C# 代码:

string connString = @"MultipleActiveResultSets=true;Data Source=db;USER id=yy;Password=xxx;Initial Catalog=dim";

string sprocname = "InsertPerfCounterData2";
string paramName = "@json";

string paramValue = SayHello(logger);

using (SqlConnection conn = new SqlConnection(connString))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand(sprocname, conn))
    {
           cmd.CommandType = CommandType.StoredProcedure;

           cmd.Parameters.Add(new SqlParameter(paramName, paramValue));

           cmd.ExecuteReader();
     }
}

I am getting an Exception Unhandled error at cmd.ExecuteReader();我在 cmd.ExecuteReader() 处收到异常未处理错误;

System.Data.SqlClient.SqlException: 'JSON text is not properly formatted. System.Data.SqlClient.SqlException: 'JSON 文本格式不正确。 Unexpected character ']' is found at position 501.'在 position 501 处发现意外字符“]”。

在此处输入图像描述

How do I modify C# code to make it work?如何修改 C# 代码以使其工作?

This is the stored procedure code:这是存储过程代码:

CREATE PROCEDURE [dbo].[InsertPerfCounterData2]
    @json NVARCHAR(max)
AS
BEGIN
    INSERT INTO dbo.PerfCounter3 ([RECORDNO], [BATCH_DATE])
        SELECT 
            GLD.RECORDNO, GLD.BATCH_DATE
        FROM 
            OPENJSON(CONCAT('[',@JSON,']')) OJ
        CROSS APPLY 
            OPENJSON(OJ.[value],'$.GLDETAIL')
                  WITH (RECORDNO varchar(30),
                        BATCH_DATE date) GLD;
END

This is example of JSON input:这是 JSON 输入的示例:

 {
    "GLDETAIL": {
      "RECORDNO": "264378-1756289-919567--accrual",
      "BATCH_DATE": "02/01/2022"
    }
  },
  {
    "GLDETAIL": {
      "RECORDNO": "264378-1756290-919568--accrual",
      "BATCH_DATE": "02/01/2022"
    }
  },

Update (5/5/2022):更新(2022 年 5 月 5 日):

I am trying to declare "result.Data" (based on @Charlieface's answer on the bottom).我正在尝试声明“result.Data”(基于@Charlieface 在底部的回答)。

If the result of resultJson is like this, and data type is String:如果resultJson的结果是这样的,数据类型是String:

resultJson =
 "[{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756289-919567-- 
  accrual\",\"BATCH_DATE\":\"02/01/2022\"}},{\"GLDETAIL\": 
  {\"RECORDNO\":\"264378-1756290-919568-- 
  accrual\",\"BATCH_DATE\":\"02/01/2022\"}}]"

How do I apply into "result.Data" properly?如何正确应用到“result.Data”?

foreach (var r in result.Data)
table.Rows.Add(r.RECORDNO, r.BATCH_DATE);

Considering you are trying to roll your own JSON writer, you are using the wrong tool for the job.考虑到您正在尝试推出自己的 JSON 编写器,您使用了错误的工具来完成这项工作。 For a bulk insert into SQL Server, the easiest and fastest method is to use SqlBulkCopy .对于 SQL 服务器的批量插入,最简单和最快的方法是使用SqlBulkCopy

For example (reading between the lines from your other question and guessing data types):例如(阅读其他问题的字里行间并猜测数据类型):

var table = new DataTable();
table.Columns.Add("RECORDNO", typeof(int));
table.Columns.Add("BATCH_DATE", typeof(DateTime));

foreach (var r in result.Data)
    table.Rows.Add(r.RECORDNO, r.BATCH_DATE);

const string connString = @"MultipleActiveResultSets=true;Data Source=db;USER id=yy;Password=xxx;Initial Catalog=dim";

using (var conn = new SqlConnection(connString))
using (var bulk = new SqlBulkCopy(conn))
{
    bulk.DestinationTableName = "PerfCounter3";
    conn.Open();
    bulk.WriteToServer(table);
}

Another option is to use a Table Valued Parameter, for which there are many examples online already.另一种选择是使用表值参数,网上已有很多示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM