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

Posted

技术标签:

【中文标题】在 for 循环中插入查询无法正常工作【英文标题】:Insert query inside for loop not working correctly 【发布时间】:2015-08-12 10:40:42 【问题描述】:

我正在处理 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 服务器在很短的时间间隔内打了很多次。有关如何处理此问题的任何指导都会有所帮助。

【问题讨论】:

生成随机密钥的逻辑是什么?您也许可以将整个过程移至存储过程。它会更简单、更快、更准确。 @SeanLange 感谢您的想法,我会将所有数据放入集合中,然后执行查询。我不知道表值参数,但我会在互联网上搜索。 @SeanLange 如果我在程序内部使用相同的逻辑,它会正常工作吗? 如果您正在谈论循环播放,则不会。当涉及到数据时,您希望尽可能避免循环。我在想你可以创建一个程序来接收要生成的新密钥并完成程序中的所有工作。您真的应该开始着手分离数据层和应用程序层。您发布的代码表明它们非常紧密耦合。 是的。假设任何字母数字字符并假设所有值的可能性相同,则可能的键数为 36^25。你不会得到重复的。 【参考方案1】:

首先,我认为我们应该避免在每次插入时打开新连接,而且我们应该始终使用 ASP.Net 内置函数作为参数(例如 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();
        
    

【讨论】:

【参考方案2】:

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

do

  couponKey = generateKey();
 while (!SearchEpinKey(epinKey));

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

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

只需更改这一行

 while (!SearchEpinKey(epinKey));

到这里

 while (!SearchEpinKey(couponKey));

【讨论】:

感谢您的编辑。我进行了编辑。但问题还是一样。 generateKey()函数的代码是什么?请发帖 它只是返回一个 25 个字符的随机数,没什么特别的。

以上是关于在 for 循环中插入查询无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

简单的 for 循环在某些手机上无法正常工作。优化不好?

Python:For循环无法正常工作

SQLite 插入查询无法正常工作

为啥 innerHTML 在 for 循环中不能正常工作?

android studio中的搜索查询无法正常工作

Ajax 无法正常工作。 PHP 无法在 SQL 中插入数据