2016-08-18 50 views
1

我将一长串employeeIds传递给employeeIdlist,然后将它们分成一个List。使用这个列表,我将参数添加到我的查询中。 我收到以下错误必须在Select命令中声明标量变量

{“必须声明标量变量\” @雇员\“”}

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; 
} 
+1

您正在添加多个参数,将您的AddWithValue保留在循环中;使用String.Join连接列表并最终只添加一个参数 – techspider

+0

我建议将sql移入存储过程并声明名为'@ EmployeeId'的输入参数,并且您有一个EmployeeId列表我还会创建一个类型并传递在列表中让数据库处理IN子句你是否熟悉在sql server中创建用户类型..? – MethodMan

回答

5

的IN

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

后删除文本,然后在foreach可以建立的参数和文本的完整列表

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

退出循环后,从StringBuilder的删除最后一个逗号

sb.Length--; 

最后,完成附加StringBuilder内容的命令文本,并且不要忘记IN子句的右括号。

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

现在可以运行使用正确的IN子句的命令和参数

+0

这很好。万分感谢。 –

+0

太棒了。它也适用于我的问题 – Muj

0

在SELECT语句必须声明的价值你变量。我已经把它变成了一个整数。如果它是一个文本值,那么你可以使用varchar(25)。

@"DECLARE @EmployeeId INT 

SELECT EmployeeId,Version 
FROM [dbo].[EmployeeVersion] 
WHERE EmployeeId in (@EmployeeId)"; 
+0

OP正在尝试在员工列表中进行搜索。请参阅'empIds'变量。 –

1

如果失败了,因为你的查询字符串,有一个参数名为@EmployeeID和您的Command对象有不同名称的许多参数的匹配列表(“@ EmployeeId1”不等于“@EmployeeId”)

看起来你似乎试图申请this的方法,这是一个好主意。

您是两条线走得到它的工作:

添加此行:

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

之前:

SqlDataReader rdr = getVersion.ExecuteReader(); 

这样做,让您的参数将匹配后@ sql字符串中存在的参数。

1

这只是另一种选择。使用堆栈溢出中使用的Dapper ORM,可以在3行代码中实现相同的结果。

您可以通过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(); 
     } 
    } 
}