随机字符串(6个字符)用作我的SQL数据库表中的主键。但是,我不知道如何处理错误并将查询重新插入数据库。
使用另一个随机字符串键将sql查询重新插入数据库的最佳解决方案是什么? (在catch块中重新插入?)
python
上面的代码是用C#编写的,但我不认为问题只是C#。因此,欢迎另一种编程语言:)
答案 0 :(得分:3)
计算随机值并针对数据库进行测试是一种缓慢/不可扩展的方法 - 它相当于猜测可用值。使用的值越多,猜测可用值的几率越大,过程变得越慢。
如果你真的不能使用Identity或Sequence或GUID,我在另一个线程中看到了一个很好的建议,就是创建一个包含" pool"独特的价值观,并使用它们。每次生成对象时,请从此表中选择并删除该行,以使该值不再可用。
请务必正确使用事务,以阻止其他并发读取器获取相同的值。
答案 1 :(得分:2)
您是否考虑过首先使用随机字符串执行SELECT查询?如果然后返回没有结果,则运行INSERT。否则,生成一个新的随机字符串,直到没有返回结果。
===
编辑代码示例。
try
{
SqlConnection con = new SqlConnection(ConnectionString);
con.Open();
int count = 1;
string key = string.Empty;
while (count > 0)
{
key = RandomString(6);
SqlCommand selectCommand = new SqlCommand("SELECT COUNT(*) FROM tableName WHERE d1 = @0", con);
selectCommand.Parameters.Add(new SqlParameter("0", key));
count = (int)selectCommand.ExecuteScalar();
}
SqlCommand insertCommand = new SqlCommand("INSERT INTO tableName(d1, d2, d3) VALUES (@0, @1, @2)", con);
insertCommand.Parameters.Add(new SqlParameter("0", key));
insertCommand.Parameters.Add(new SqlParameter("1", "values"));
insertCommand.Parameters.Add(new SqlParameter("2", DateTime.Now));
var rowCount = insertCommand.ExecuteNonQuery();
con.Close();
if (rowCount < 1)
{
label.Text = "OMG it is Fail :(";
return false;
}
else
{
label.Text = "HEY ~~~ inserted";
return true;
}
}
catch (Exception ex)
{
label.Text = ex.Message;
return false;
}
===
老实说,我所展示的上述方法非常糟糕。它解决了您在主键中发生冲突的问题,但它并不是正确的方法。我会推荐一些改变之一:
Guid.NewGuid()
作为该值,您可以认为该值是唯一的。HashSet<string>
。然后,当您在RandomString(int)
方法中生成新的随机字符串时,请检查该HashSet以查看它是否存在。如果没有,继续插入,否则生成一个新的。答案 2 :(得分:-1)
您可以尝试以下
将Try / Catch块放在带有标志的循环中
如果有任何错误,请在Catch块中设置标志以继续循环。
答案 3 :(得分:-2)
为什么不使用存储过程?
因此,在存储过程中生成随机密钥(使用类似GUID的东西,使用最后6个字符或类似的东西)。
然后在同一个存储过程中,在插入id之前,首先执行exists语句检查。如果ID存在,则重新生成ID,如果不存在,则插入。
所以你的c#代码只会调用那个存储过程。在c#中执行插入或任何sql语句都很糟糕,因为它很容易被sql注入。