条件未返回正确结果的SQL计数

时间:2018-03-10 06:59:26

标签: c# sql sql-server count where-clause

我的停车管理应用程序有一个汽车表(sql server),其中每个汽车记录在登记时由app自动分配。

我正在努力实施它。我的概念是,我将在变量“slotx”中保留“1”值,然后如果表的“Slot”列中存在相同的值,则将使用查询。如果它已经存在,则“slotx”值增加1,并再次查询数据库以检查表中是否存在下一个数字,即“2”,并且此过程继续,直到“slotx”值与任何记录不匹配为止汽车表,此时(当表格中没有相同的值时)“slotx”的值被分配给即将到来的车辆的表的“Slot”列。

但代码不起作用,我试图找出使用断点的问题,并希望正确地发现即使没有任何匹配的记录,后续查询总是返回值'1',因此导致无限循环。 “从汽车中选择COUNT(插槽),插槽= @slot;”

代码:

//variables/member declaration
public static int slotx = 1;
private static string searchcarslotauto = "Select COUNT(Slot) From Cars Where Slot= @slot;";

//sqlcommand setup
SqlCommand checkreservedcar = new SqlCommand(searchcarslotauto, con);
checkreservedcar.Parameters.AddWithValue("@slot", slotx);

//CheckIn related
con.Open();
Loop: int isreservereader = (int)checkreservedcar.ExecuteScalar();
if (isreservereader != 0)
{
     slotx++;
     goto Loop;
}
else
{
     insertcarcmd.ExecuteNonQuery();
}
con.Close();

示例输入数据(Table Cars): - 序列号:1 Reg#:JGI-12-5888 DateTimeIn:3/5/2018 9:52:00 AM Slot:1订阅:False;

预期结果:如果变量“slotx”值与“Slot”列的任何记录值都不匹配,则查询将返回“0”值,而不是。

对于非常冗长的问题,我不能简单地解释一下。请有人指导我!

已经尝试过替代查询无济于事。 Count based on condition in SQL Server

2 个答案:

答案 0 :(得分:2)

请停止您正在做的事情,忘记您为此特定问题所做的所有事情,并跳过了解有关数据库规范化的一些信息。身份。

简而言之,请考虑以下情况:

  1. 您的应用程序收到了插槽请求
  2. 它ping SQL服务器并获取2是免费的信息
  3. 另一个请求来到应用程序
  4. (第一个请求尚未写入)应用程序再次ping SQL服务器并获取插槽2是免费的信息
  5. 两个插槽请求都是针对插槽2编写的 - 实际上,您已经丢失了一条记录
  6. 底线:拥有应用程序检查身份是一个非常糟糕的主意。这必须以事务方式或使用IDENTITY列(现在更适合您)。

答案 1 :(得分:1)

您的代码中的问题很可能出在调用AddWithValue中。在那里你要为命令添加一个参数,初始值为slotx,我猜是1。然后在你的" Loop"你不断更新slotx的值,但这只是更新那个静态变量,而不是你在命令参数中存储的值。请参阅Tim Schmelter对this question的已接受答案,以了解为每个循环迭代更新该参数的方法。另一种方法是保持AddWithValue返回的SqlParameter对象并更新该对象。

一些额外的评论:
- 在此问题的另一个答案中遵循dee zg的建议,并仔细查看使用sql事务以确保相同的插槽未分配给多个汽车。
- 不要使用goto标签,当它没有做任何for / while循环完美实现的任何事情时更是如此 - 考虑使用Numbers表,这样你就可以在SQL查询中使用WHERE NOT EXISTS并只用一个查询解决问题,根本不需要循环。 Here链接到Aaron Bertrand关于这些表格的文章。

循环的代码可能如下所示:

con.Open();
while ((int)checkreservedcar.ExecuteScalar() != 0)
{
     slotx++;
     checkreservedcar .Parameters["@slot"].Value = slotx;
}
insertcarcmd.ExecuteNonQuery();
con.Close();