使用存储过程在数据库中插入列表记录

发布于 2025-01-08 13:49:27 字数 1170 浏览 5 评论 0原文

我有一个使用存储过程插入 SQL Server 数据库的记录列表。目前我就是这样做的,但是有更好的方法吗?

我在应用程序的高峰时段每秒插入 100-200 行。存储过程仅获取值并插入新行

    public void InsertRecords(List<stRecord> records)
    {
        foreach (var item in records)
        {
            if (CheckforDuplicateRecord(item) == false)
            {
                using (con = new SqlConnection(connectionString))
                {
                    con.Open();

                    SqlCommand cmd = new    SqlCommand(StoredProcedures.Service_Insert_record.ToString(), con);
                    cmd.CommandType = CommandType.StoredProcedure;

                    cmd.Parameters.Add("@item1", SqlDbType.NChar);
                    cmd.Parameters.Add("@item2", SqlDbType.NChar);

                    cmd.Parameters[0].Value = item.localUsername;
                    cmd.Parameters[1].Value = item.BetfairUsername;


                    try
                    {
                        cmd.ExecuteNonQuery();
                    }
                    catch (Exception exp)
                    {
                        throw exp;
                    }
                }
            }
        }
    }

I have a list of records inserting into a SQL Server database using a stored procedure. Currently I am doing it this way but is there any better way?

I am inserting 100-200 rows per/sec on peak hours of my app. The stored procedure only gets the values and inserts the new row

    public void InsertRecords(List<stRecord> records)
    {
        foreach (var item in records)
        {
            if (CheckforDuplicateRecord(item) == false)
            {
                using (con = new SqlConnection(connectionString))
                {
                    con.Open();

                    SqlCommand cmd = new    SqlCommand(StoredProcedures.Service_Insert_record.ToString(), con);
                    cmd.CommandType = CommandType.StoredProcedure;

                    cmd.Parameters.Add("@item1", SqlDbType.NChar);
                    cmd.Parameters.Add("@item2", SqlDbType.NChar);

                    cmd.Parameters[0].Value = item.localUsername;
                    cmd.Parameters[1].Value = item.BetfairUsername;


                    try
                    {
                        cmd.ExecuteNonQuery();
                    }
                    catch (Exception exp)
                    {
                        throw exp;
                    }
                }
            }
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤独患者 2025-01-15 13:49:27

这正是表值参数的用途 - 您可以一次性传递列表。

在 SQL Server 中:

CREATE TYPE dbo.Usernames AS TABLE
(
  localUsername   NVARCHAR(32),
  BetfairUsername NVARCHAR(32)
);
GO

CREATE PROCEDURE dbo.Service_Insert_MultipleRows
  @u AS dbo.Usernames READONLY
AS
BEGIN
  SET NOCOUNT ON;

  INSERT INTO dbo.DestinationTable(localUsername, BetfairUsername)
    SELECT localUsername, BetfairUsername FROM @u;
END
GO

现在在 C# 中:

DataTable tvp = new DataTable();
tvp.Columns.Add(new DataColumn("localUsername"));
tvp.Columns.Add(new DataColumn("BetfairUsername"));

foreach(var item in records)
{ 
    tvp.Rows.Add(item.localUsername, item.BetfairUsername); 
}

using (con)
{
    SqlCommand cmd = new SqlCommand("Service_Insert_MultipleRows", con);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter tvparam = cmd.Parameters.AddWithValue("@u", tvp);
    tvparam.SqlDbType = SqlDbType.Structured;
    con.Open();
    cmd.ExecuteNonQuery();
}

This is exactly what table-valued parameters are for - you can pass your list in one shot.

In SQL Server:

CREATE TYPE dbo.Usernames AS TABLE
(
  localUsername   NVARCHAR(32),
  BetfairUsername NVARCHAR(32)
);
GO

CREATE PROCEDURE dbo.Service_Insert_MultipleRows
  @u AS dbo.Usernames READONLY
AS
BEGIN
  SET NOCOUNT ON;

  INSERT INTO dbo.DestinationTable(localUsername, BetfairUsername)
    SELECT localUsername, BetfairUsername FROM @u;
END
GO

Now in C#:

DataTable tvp = new DataTable();
tvp.Columns.Add(new DataColumn("localUsername"));
tvp.Columns.Add(new DataColumn("BetfairUsername"));

foreach(var item in records)
{ 
    tvp.Rows.Add(item.localUsername, item.BetfairUsername); 
}

using (con)
{
    SqlCommand cmd = new SqlCommand("Service_Insert_MultipleRows", con);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter tvparam = cmd.Parameters.AddWithValue("@u", tvp);
    tvparam.SqlDbType = SqlDbType.Structured;
    con.Open();
    cmd.ExecuteNonQuery();
}
暮光沉寂 2025-01-15 13:49:27

您可以做的一件显而易见的事情是:在方法开始时仅创建 一次 SqlCommand - 一遍又一遍地创建它没有意义!

public void InsertRecords(List<stRecord> records)
{
   using (con = new SqlConnection(connectionString))
   using (SqlCommand cmd = new SqlCommand(StoredProcedures.Service_Insert_record.ToString(), con))
   {
       cmd.CommandType = CommandType.StoredProcedure;

       // are those paramters *REALLY* just 1 character long?? 
       // that's what you have now, with the way you define it!
       cmd.Parameters.Add("@item1", SqlDbType.NChar);
       cmd.Parameters.Add("@item2", SqlDbType.NChar);

       // otherwise, you need to define the LENGTH of the NCHAR parameter!
       // cmd.Parameters.Add("@item2", SqlDbType.NChar, 15);

       foreach (var item in records)
       {
           if (CheckforDuplicateRecord(item) == false)
           {
              cmd.Parameters["@item1"].Value = item.localUsername;
              cmd.Parameters["@item2"].Value = item.BetfairUsername;

              try
              {
                 con.Open();
                 cmd.ExecuteNonQuery();
                 con.Close();
              }
              catch (Exception exp)
              {
                 throw;
              }
            }
       }
    }

One obvious thing you could do: create the SqlCommand only once at the beginning of the method - no point in creating it over and over and over again!

public void InsertRecords(List<stRecord> records)
{
   using (con = new SqlConnection(connectionString))
   using (SqlCommand cmd = new SqlCommand(StoredProcedures.Service_Insert_record.ToString(), con))
   {
       cmd.CommandType = CommandType.StoredProcedure;

       // are those paramters *REALLY* just 1 character long?? 
       // that's what you have now, with the way you define it!
       cmd.Parameters.Add("@item1", SqlDbType.NChar);
       cmd.Parameters.Add("@item2", SqlDbType.NChar);

       // otherwise, you need to define the LENGTH of the NCHAR parameter!
       // cmd.Parameters.Add("@item2", SqlDbType.NChar, 15);

       foreach (var item in records)
       {
           if (CheckforDuplicateRecord(item) == false)
           {
              cmd.Parameters["@item1"].Value = item.localUsername;
              cmd.Parameters["@item2"].Value = item.BetfairUsername;

              try
              {
                 con.Open();
                 cmd.ExecuteNonQuery();
                 con.Close();
              }
              catch (Exception exp)
              {
                 throw;
              }
            }
       }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文