1

I am passing a long list of employeeIds to employeeIdlist and I split them into a List. Using this list I am adding parameters to my query. I am getting the following error

{"Must declare the scalar variable \"@EmployeeId\"."}

public List<versionInfo> GetVersion(string  employeeIdlist)
{
    DbHelper helper = new DbHelper();
    List<versionInfo> empVerInfo = new List<versionInfo>();

    using (SqlConnection conn = new SqlConnection(connString))
    {              
        conn.Open();
        using (SqlCommand getVersion = new SqlCommand())
        {
            getVersion.Connection = conn;
            getVersion.CommandText = @"SELECT EmployeeId,Version 
                                                FROM [dbo].[EmployeeVersion]
                                                WHERE EmployeeId in (@EmployeeId)";

            getVersion.CommandType = CommandType.Text;
            List<int> empIds = employeeIdlist.Split(',').Select(int.Parse).ToList();
            StringBuilder sb = new StringBuilder();
            int i = 0;
            foreach (var emp in empIds)
            {
                // IN clause
                sb.Append("@EmployeeId" + i.ToString() + ",");
                // parameter
                getVersion.Parameters.AddWithValue("@EmployeeId" + i.ToString(), emp);
                i++;
            }

           // getVersion.Parameters.AddWithValue("@EmployeeId", employeeIdlist);
            SqlDataReader rdr = getVersion.ExecuteReader();
            while (rdr.Read())
            {
                versionInfo vi = new versionInfo();
                vi.employeeId = helper.GetDb<int>(rdr, "EmployeeId");
                vi.version = helper.GetDb<decimal>(rdr, "Version");
                empVerInfo.Add(vi);                      
            }
            rdr.Close();
        }
        conn.Close();
    }
    return empVerInfo;
}
MethodMan
  • 18,625
  • 6
  • 34
  • 52
r mk r
  • 289
  • 2
  • 4
  • 14
  • 1
    You are adding multiple parameter by keeping your AddWithValue inside the loop; Use String.Join to concatenate the list and finally add only one parameter – techspider Aug 18 '16 at 20:20
  • I would suggest moving the sql over into a stored procedure and declaring a input param named `@EmployeeId` you have a list of EmployeeId's I would also make a type and pass in the List to let the Database handle the IN Clause are you familiar with creating user types in sql server..? – MethodMan Aug 18 '16 at 20:22

4 Answers4

5

Remove the text after the IN

getVersion.CommandText = @"SELECT EmployeeId,Version 
                          FROM [dbo].[EmployeeVersion]
                          WHERE EmployeeId in (";

then the foreach could build the full list of parameters and texts

foreach (var emp in empIds)
{
    sb.Append("@EmployeeId" + i.ToString() + ",");
    getVersion.Parameters.AddWithValue("@EmployeeId" + i.ToString(), emp);
    i++;
}

after exiting the loop remove the last comma from the StringBuilder

sb.Length--;

finally, complete the command text appending the content of the StringBuilder and do not forget the closing parenthesys for the IN clause.

getVersion.CommandText += sb.ToString() + ")";

Now you can run the command with the correct IN clause and a matching list of parameters

Steve
  • 213,761
  • 22
  • 232
  • 286
1

If fails because your string query has one parameter named @EmployeeId and your Command object has many parameters with different names ("@EmployeeId1" is not equal to "@EmployeeId")

It seems like you are trying to apply this approach, which is a good idea.

You are two lines away of getting it to work:

Add this lines:

sb.Lenght--;
getVersion.CommandText = getVersion.CommandText.Replace("@EmployeeId",sb.ToString())

just before:

SqlDataReader rdr = getVersion.ExecuteReader();

After doing that your added parameters will match those @parameters existing in the sql string.

Community
  • 1
  • 1
Gerardo Grignoli
  • 14,058
  • 7
  • 57
  • 68
1

This is just another option. You can achieve the same result in 3 lines of code using Dapper ORM used in Stack Overflow.

You can download via NuGet.

public class VersionInfo
{
    public int EmployeeId { get; set; }
    public decimal Version { get; set; }
}

class Program
{
    public static string connString = "...";

    static void Main(string[] args)
    {
        var result = GetVersion(new List<int> {1, 2});
        Console.ReadLine();
    }

    public static List<VersionInfo> GetVersion(IList<int> employeeIds)
    {
        using (IDbConnection conn = new SqlConnection(connString))
        {
            conn.Open();
            var entities = conn.Query<VersionInfo>(
                @"SELECT EmployeeId, Version from EmployeeVersion WHERE EmployeeId IN @EmployeeIds",
                new {EmployeeIds = employeeIds});

            return entities.ToList();
        }
    }
}
Win
  • 61,100
  • 13
  • 102
  • 181
0

On your select statement you have to declare a value for your variable. I have made it an Integer. If it is a text value, then you can use varchar(25).

@"DECLARE @EmployeeId INT

SELECT EmployeeId,Version 
FROM [dbo].[EmployeeVersion]
WHERE EmployeeId in (@EmployeeId)";
bwilliamson
  • 391
  • 1
  • 13