在 C# 代码中从 JSON 向 SQL 服务器数据库插入超过 1000 行

INSERT more than 1000 rows into SQL Server database from JSON in C# code

我收到一条错误消息:

The number of row value expressions in the INSERT statement exceeds the maximum allowed number of 1000 row values.

我正在从 API 呼叫中获取 JSON 数据。当我试图将它插入我的 SQL 服务器数据库时,我收到了错误。我正在尝试插入 3000 行。我该如何解决这个问题? APi的调用结果存储在变量“body”中,然后反序列化到变量“json”中。

这是我的代码:

using (var response = await client.SendAsync(request))
{
    response.EnsureSuccessStatusCode();
    var body = await response.Content.ReadAsStringAsync();

    var json = JsonConvert.DeserializeObject<Root>(body);
    var Api = json.api;

    string SqlString = "INSERT INTO land.leagues(" +
                                                "league_id" +
                                                ",name" +
                                                ",type" +
                                                ",country" +
                                                ",country_code" +
                                                ",season" +
                                                ",season_start" +
                                                ",season_end" +
                                                ",logo" +
                                                ",flag" +
                                                ",standings" +
                                                ",is_current" +
                                                ",coverage_standings" +
                                                ",coverage_players" +
                                                ",coverage_topScorers" +
                                                ",coverage_predictions" +
                                                ",coverage_odds" +
                                                ",coverage_fixtures_events" +
                                                ",coverage_fixtures_lineups" +
                                                ",coverage_fixtures_statistics" +
                                                ",coverage_fixtures_playersStatistics" +
                                                ",created" +
                                                ") VALUES"; 


    foreach (var a in Api.leagues)
    {
        SqlString += "(" +
                                 "'" + a.league_id +
                                 "','" + a.name.Replace("'","`") + 
                                 "','" + a.type +
                                 "','" + a.country +
                                 "','" + a.country_code +
                                 "','" + a.season +
                                 "','" + a.season_start +
                                 "','" + a.season_end +
                                 "','" + a.logo +
                                 "','" + a.flag +
                                 "','" + a.standings +
                                 "','" + a.is_current +
                                 "','" + a.coverage.standings +
                                 "','" + a.coverage.players +
                                 "','" + a.coverage.topScorers +
                                 "','" + a.coverage.predictions +
                                 "','" + a.coverage.odds +
                                 "','" + a.coverage.fixtures.events +
                                 "','" + a.coverage.fixtures.lineups +
                                 "','" + a.coverage.fixtures.statistics +
                                 "','" + a.coverage.fixtures.players_statistics +
                                 "','" + DateTime.Now +
                                 "'),";
    }

    SqlConnection con = new SqlConnection(@"_ConnectionString_");
    SqlCommand cmd;

    con.Open();
    cmd = new SqlCommand("TRUNCATE TABLE land.leagues " + SqlString.Remove(SqlString.Length - 1), con);

    cmd.ExecuteNonQuery();    
}

这些都是我的类:

public class Fixtures
{
    public bool events { get; set; }
    public bool lineups { get; set; }
    public bool statistics { get; set; }
    public bool players_statistics { get; set; }
}

public class Coverage
{
    public bool standings { get; set; }
    public Fixtures fixtures { get; set; }
    public bool players { get; set; }
    public bool topScorers { get; set; }
    public bool predictions { get; set; }
    public bool odds { get; set; }
}

public class League
{
    public int league_id { get; set; }
    public string name { get; set; }
    public string type { get; set; }
    public string country { get; set; }
    public string country_code { get; set; }
    public int season { get; set; }
    public string season_start { get; set; }
    public string season_end { get; set; }
    public string logo { get; set; }
    public string flag { get; set; }
    public int standings { get; set; }
    public int is_current { get; set; }
    public Coverage coverage { get; set; }
}

public class Api
{
    public int results { get; set; }
    public List<League> leagues { get; set; }
}

public class Root
{
    public Api api { get; set; }
}

您可以通过这种方式插入的最大行数是 1000,所以这个错误是正常的。我会简单地将我的行分成数千行,并为每批行创建一个新的 INSERT 语句。希望这是有道理的:)

您应该逐行插入。

https://www.red-gate.com/simple-talk/sql/performance/comparing-multiple-rows-insert-vs-single-row-insert-with-three-data-load-methods/

要点 - 23 列意味着一次插入超过 2 列是不值得的。时间方面,单行插入几乎和多行插入一样快。在某些情况下,对参数进行字符串化可以提高 50%,但 IMO 不值得。如果您将列减少到 2 甚至 7,那可能是值得的。

对这些估计持保留态度 - 盒子的性能可能会影响相对收益。

当然,让您的行插入一次一个,这样可以轻松地参数化您的查询并保持清晰,同时消除 sql 注入的可能性。不必每次都编译 sql,同时在客户端完成大部分参数工作也有很大帮助。