简体   繁体   中英

Sql count where condition is not returning correct result

I have a Cars table(sql server) for my parking management application in which each car record is to be assigned unique Slot automatically by app upon checkin.

I'm struggling in implementing it. The concept is that I will keep '1' value in a variable "slotx" and will then figure out using queries if there is already same value present in the 'Slot' column of table or not. If its already there then "slotx" value is incremented by 1 and database is again queried to check if next number ie '2' exists in table or not, and this process continues until the "slotx" value doesn't match any record in Cars table, at this point(when same value is not present in table) this value of "slotx" is assigned to 'Slot' column of table for coming vehicle.

But code is not working, I have tried to figure out problem using breakpoints and hopefully correctly spotted that following query is always returning value '1' even if there is not any matching record, hence causing infinite loop. "Select COUNT(Slot) From Cars Where Slot= @slot;"

Code:

//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();

Sample input Data(Table Cars):- Serial: 1 Reg#: JGI-12-5888 DateTimeIn: 3/5/2018 9:52:00 AM Slot: 1 Subscribed: False;

Expected Result: If there variable "slotx" value doesn't match any record value of 'Slot' column the query is expected to return '0' value, which it doesn't.

Sorry for very lengthy question I couldn't explain it briefly. Kindly someone guide me!

Already tried alternative query to no avail. Count based on condition in SQL Server

Please stop with what you're doing, forget everything you did so far for this particular question and jump to learn a bit about database normalization & identities.

In short, consider this scenario:

  1. Your application gets a request for slot
  2. It pings SQL server and gets info that 2 is free
  3. Another request comes to application
  4. (First request was not written in yet) Application again pings SQL server and gets info that slot 2 is free
  5. Both slot requests are written for slot 2 - effectively, you've lost one record

Bottomline: having application check identities is a very bad idea. That has to be done in transactional way or using IDENTITY columns (better for you for now).

Most likely the problem in your code is in the call AddWithValue . There you are adding a parameter to the command with the initial value of slotx , a 1 I guess. Then in your "Loop" you keep updating the value of slotx, but this is just updating that static variable, not the value you stored in the command parameter. See the accepted answer to this question by Tim Schmelter to see a way to update that parameter for each loop iteration. Another way could be to keep the SqlParameter object returned by AddWithValue and update that one.

A few extra comments:
- Follow the advice by dee zg in another answer to this question and look carefully about using sql transactions to ensure that the same slot not assigned to more than one car.
- Don't use the goto tag, even more when it doesn't do anything that a for/while loop would perfectly accomplish
- Consider using a Numbers table, that way you could use a WHERE NOT EXISTS in your SQL query and solve the problem with just one query, no needing the loop at all. Here a link to an article by Aaron Bertrand talking about those tables.

The code for your loop could look something like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM