在for循环中插入查询无法正常工作

时间:2015-05-29 14:05:39

标签: c# sql-server tsql ado.net

我正在研究Asp .Net项目。所以我有一个页面,我正在生成随机优惠券密钥。因此用户输入数量并生成。

所以我做了什么,我根据数量放了一个for循环,在for循环中我创建了一个随机密钥并在DB中搜索密钥(密钥是唯一的)然后在DB中插入数据。

代码:

for (int i = 0; i < quantity; i++)
{
  do
  {
    couponKey = generateKey();
   } while (!SearchEpinKey(couponKey));

   conn = new SqlConnection(connString);
   conn.Open();

   using (SqlCommand cmd = new SqlCommand())
   {
       cmd.Connection = conn;
       cmd.CommandType = CommandType.Text;
       string query = "INSERT INTO CouponStock (coupon_key,  status, created_on)";
       query += "VALUES('" + couponKey + "','Unused', GETDATE())";
       cmd.CommandText = query; 
       cmd.ExecuteNonQuery();

    }
    conn.Close();
}

在循环内部,Flow就像:

-Genrate random key
-Search if random key exists or not in db
-If found similar then again generate random key
-Insert the data in DB

因此,当我为10或15等较小的数量运行此页面时,它的工作正常。但是,当我去50或100时,它会插入随机数量的行,比如某个时间24,有时是48.然后应用程序会在此之后挂起。我认为Sql服务器在短时间内打了很多时间。有关如何处理此问题的任何指导都会有所帮助。

2 个答案:

答案 0 :(得分:0)

我能找到的唯一原因是因为这个

do
{
  couponKey = generateKey();
} while (!SearchEpinKey(epinKey));

如果您在couponKey查询中使用INSERT,为什么要使用SearchEpinKey(epinKey)?你在哪里搜索DB中的couponKey

您被分配到generateKey()couponKey变量,并且您正在检查epinKey,我相信当epinKey已经存储在数据库中时它会挂起(无限循环) ),因为epinKey总是相同的,即使你为couponKey确定一个新值

只需更改此行

} while (!SearchEpinKey(epinKey));

到这个

} while (!SearchEpinKey(couponKey));

答案 1 :(得分:0)

首先我认为我们应该避免在每个插件上打开一个新连接,我们也应该总是使用ASP.Net build in function for parameter(例如AddWithValue),因为它们有助于避免SQL Injection

   
    var couponList  = new System.Collections.Generic.List<String>(); 
    var query = "INSERT INTO CouponStock(coupon_key, status, created_on) VALUES(@coupon_key, @status, GETUTCDATE());";

    using (SqlConnection conn = new SqlConnection(connString)) 
    {
        try
        {
            conn.Open();

            do{
                var couponKey = generateKey();

                //return early for readability
                if(!SearchEpinKey(couponKey)) continue;
                if(couponList.Contains(couponKey)) continue;

                //add to coupon list to ensure newly generated key does not duplicate
                couponList.Add(couponKey);

                SqlCommand cmd = conn.CreateCommand(query);
                cmd.Parameters.AddWithValue("@coupon_key", couponKey);
                cmd.Parameters.AddWithValue("@status", "Unused");

                cmd.ExecuteNonQuery();
            }
            while (couponList.Count < quantity);
        }
        catch (Exception e)
        {
            // handle exceptions or re-throw them...
        }
        finally
        {
            conn.Close();
        }
    }