无法迭代 JSON 数组
Can't iterate a JSON array
我正在尝试使用“SqlBulkCopy”以不同的方式将数据放入 SQL,但出现了一些错误。
底部是目前可以正常工作的部分。
static void Main(string[] args)
{
ILogger logger = Bootstrap.Logger("");
string paramValue = SayHello(logger);
string connString = @"Data Source=net;USER id=admin;Password=ess;Initial Catalog=fin";
string sprocname = "InsertPerfCounterData3";
string paramName = "@json";
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();
}
}
目前,paramValue 有这样的输出:
"[{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756289-919567--accrual\",\"BATCH_DATE\":\"02/01/2022\"}},
{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756290-919568--accrual\",\"BATCH_DATE\":\"02/01/2022\"}}]"
我正在尝试使用底部代码,而不是:
var table = new DataTable();
table.Columns.Add("RECORDNO", typeof(int));
table.Columns.Add("BATCH_DATE", typeof(DateTime));
foreach (var r in paramValue.Data)
table.Rows.Add(r.RECORDNO, r.BATCH_DATE);
const string connString1 = @"Data Source=net;USER id=admin;Password=ess;Initial Catalog=fin";
using (var conn = new SqlConnection(connString))
using (var bulk = new SqlBulkCopy(conn))
{
bulk.DestinationTableName = "PerfCounter3";
conn.Open();
bulk.WriteToServer(table);
}
这是我出错的地方,我不确定如何修改:
更新 (5/10/2022):
我需要一些关于如何正确插入数据的帮助,因为我收到如下所示的错误:
我没有包括所有其他 Class 代码。
我需要一些帮助来将每一行迭代到数据库。
static void Main(string[] args)
{
ILogger logger = Bootstrap.Logger("");
string paramValue = SayHello(logger);
const string connString = @"Data Source=net;USER id=admin;Password=ess;Initial Catalog=fin";
var data = JsonConvert.DeserializeObject<Wossit[]>(paramValue);
var table = new DataTable();
table.Columns.Add("RECORDNO", typeof(Char));
table.Columns.Add("BATCH_DATE", typeof(DateTime));
foreach (var record in data)
table.Rows.Add($"{record.Detail.RecordNumber}, {record.Detail.BatchDate}");
using (var conn = new SqlConnection(connString))
using (var bulk = new SqlBulkCopy(conn))
{
bulk.DestinationTableName = "PerfCounter4";
conn.Open();
bulk.WriteToServer(table);
}
}
HResult=0x80070057
Message=String must be exactly one character long.Couldn't store
<264378-1756289-919567--accrual, 2/1/2022 12:00:00 AM> in RECORDNO
Column. Expected type is Char.
Source=System.Data.Common
StackTrace:
at System.Data.DataColumn.set_Item(Int32 record, Object value)
at System.Data.DataTable.NewRecordFromArray(Object[] value)
at System.Data.DataRowCollection.Add(Object[] values)
at Sage0413.Program.Main(String[] args) in C:\..\Main.cs:line 65
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
FormatException: String must be exactly one character long.
您似乎缺少 JSON 解析步骤。您不能神奇地从字符串获取数据——您需要解释数据;也许是这样的:
using Newtonsoft.Json;
using System;
string json = "[{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756289-919567--accrual\",\"BATCH_DATE\":\"02/01/2022\"}},{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756290-919568--accrual\",\"BATCH_DATE\":\"02/01/2022\"}}]";
var data = JsonConvert.DeserializeObject<Wossit[]>(json);
foreach (var record in data)
{
Console.WriteLine($"{record.Detail.RecordNumber}, {record.Detail.BatchDate}");
}
class Wossit
{
[JsonProperty("GLDETAIL")]
public Somet Detail { get; set; }
}
class Somet
{
[JsonProperty("RECORDNO")]
public string RecordNumber { get; set; }
[JsonProperty("BATCH_DATE")]
public DateTime BatchDate { get; set; }
}
你的异常告诉你发生了什么。您正在尝试将 VARCHAR
插入数据库中的 CHAR
字段(您最初作为 INT
的 RECORDNO 字段)。
A CHAR
是一个字符,您的 RECORDNO 是一串可变字符 -- VARCHAR
,最接近匹配 c# string
.
尝试将 table.Columns.Add("RECORDNO", typeof(Char));
更改为 table.Columns.Add("RECORDNO", typeof(String));
以查看是否可以解决您的问题。
编辑:
您似乎也在此处将单个字符串传递到 table 行:
table.Rows.Add($"{record.Detail.RecordNumber}, {record.Detail.BatchDate}");
这可能不是您想要的。
使用 Add(Object[])
方法将数据添加到 table 可能会有所帮助。我认为您目前正在将字符数组传递给该方法——$"{record.Detail.RecordNumber}, {record.Detail.BatchDate}"
可能会被解释为字符数组并被毫无问题地接受为 add 方法的参数。
可能会改变
table.Rows.Add($"{record.Detail.RecordNumber}, {record.Detail.BatchDate}");
至
table.Rows.Add(new object[]{record.Detail.RecordNumber, record.Detail.BatchDate});
将解决您的问题。
我正在尝试使用“SqlBulkCopy”以不同的方式将数据放入 SQL,但出现了一些错误。
底部是目前可以正常工作的部分。
static void Main(string[] args)
{
ILogger logger = Bootstrap.Logger("");
string paramValue = SayHello(logger);
string connString = @"Data Source=net;USER id=admin;Password=ess;Initial Catalog=fin";
string sprocname = "InsertPerfCounterData3";
string paramName = "@json";
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();
}
}
目前,paramValue 有这样的输出:
"[{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756289-919567--accrual\",\"BATCH_DATE\":\"02/01/2022\"}},
{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756290-919568--accrual\",\"BATCH_DATE\":\"02/01/2022\"}}]"
我正在尝试使用底部代码,而不是:
var table = new DataTable();
table.Columns.Add("RECORDNO", typeof(int));
table.Columns.Add("BATCH_DATE", typeof(DateTime));
foreach (var r in paramValue.Data)
table.Rows.Add(r.RECORDNO, r.BATCH_DATE);
const string connString1 = @"Data Source=net;USER id=admin;Password=ess;Initial Catalog=fin";
using (var conn = new SqlConnection(connString))
using (var bulk = new SqlBulkCopy(conn))
{
bulk.DestinationTableName = "PerfCounter3";
conn.Open();
bulk.WriteToServer(table);
}
这是我出错的地方,我不确定如何修改:
更新 (5/10/2022):
我需要一些关于如何正确插入数据的帮助,因为我收到如下所示的错误:
我没有包括所有其他 Class 代码。
我需要一些帮助来将每一行迭代到数据库。
static void Main(string[] args)
{
ILogger logger = Bootstrap.Logger("");
string paramValue = SayHello(logger);
const string connString = @"Data Source=net;USER id=admin;Password=ess;Initial Catalog=fin";
var data = JsonConvert.DeserializeObject<Wossit[]>(paramValue);
var table = new DataTable();
table.Columns.Add("RECORDNO", typeof(Char));
table.Columns.Add("BATCH_DATE", typeof(DateTime));
foreach (var record in data)
table.Rows.Add($"{record.Detail.RecordNumber}, {record.Detail.BatchDate}");
using (var conn = new SqlConnection(connString))
using (var bulk = new SqlBulkCopy(conn))
{
bulk.DestinationTableName = "PerfCounter4";
conn.Open();
bulk.WriteToServer(table);
}
}
HResult=0x80070057
Message=String must be exactly one character long.Couldn't store
<264378-1756289-919567--accrual, 2/1/2022 12:00:00 AM> in RECORDNO
Column. Expected type is Char.
Source=System.Data.Common
StackTrace:
at System.Data.DataColumn.set_Item(Int32 record, Object value)
at System.Data.DataTable.NewRecordFromArray(Object[] value)
at System.Data.DataRowCollection.Add(Object[] values)
at Sage0413.Program.Main(String[] args) in C:\..\Main.cs:line 65
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
FormatException: String must be exactly one character long.
您似乎缺少 JSON 解析步骤。您不能神奇地从字符串获取数据——您需要解释数据;也许是这样的:
using Newtonsoft.Json;
using System;
string json = "[{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756289-919567--accrual\",\"BATCH_DATE\":\"02/01/2022\"}},{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756290-919568--accrual\",\"BATCH_DATE\":\"02/01/2022\"}}]";
var data = JsonConvert.DeserializeObject<Wossit[]>(json);
foreach (var record in data)
{
Console.WriteLine($"{record.Detail.RecordNumber}, {record.Detail.BatchDate}");
}
class Wossit
{
[JsonProperty("GLDETAIL")]
public Somet Detail { get; set; }
}
class Somet
{
[JsonProperty("RECORDNO")]
public string RecordNumber { get; set; }
[JsonProperty("BATCH_DATE")]
public DateTime BatchDate { get; set; }
}
你的异常告诉你发生了什么。您正在尝试将 VARCHAR
插入数据库中的 CHAR
字段(您最初作为 INT
的 RECORDNO 字段)。
A CHAR
是一个字符,您的 RECORDNO 是一串可变字符 -- VARCHAR
,最接近匹配 c# string
.
尝试将 table.Columns.Add("RECORDNO", typeof(Char));
更改为 table.Columns.Add("RECORDNO", typeof(String));
以查看是否可以解决您的问题。
编辑:
您似乎也在此处将单个字符串传递到 table 行:
table.Rows.Add($"{record.Detail.RecordNumber}, {record.Detail.BatchDate}");
这可能不是您想要的。
使用 Add(Object[])
方法将数据添加到 table 可能会有所帮助。我认为您目前正在将字符数组传递给该方法——$"{record.Detail.RecordNumber}, {record.Detail.BatchDate}"
可能会被解释为字符数组并被毫无问题地接受为 add 方法的参数。
可能会改变
table.Rows.Add($"{record.Detail.RecordNumber}, {record.Detail.BatchDate}");
至
table.Rows.Add(new object[]{record.Detail.RecordNumber, record.Detail.BatchDate});
将解决您的问题。