必须在Select命令中声明标量变量

时间:2016-08-18 20:12:08

标签: c# sql-server

我将一长串employeeId传递给employeeIdlist,然后将它们分成一个列表。使用此列表我将向查询添加参数。 我收到以下错误

  

{"必须声明标量变量\" @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;
}

4 个答案:

答案 0 :(得分: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子句和匹配的参数列表

运行该命令

答案 1 :(得分:1)

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

您似乎正在尝试应用this方法,这是一个好主意。

离开它还有两行:

添加以下行:

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

就在之前:

SqlDataReader rdr = getVersion.ExecuteReader();

执行此操作后,您添加的参数将与sql字符串中存在的@parameters匹配。

答案 2 :(得分:1)

这只是另一种选择。使用Stack Overflow中使用的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();
        }
    }
}

答案 3 :(得分:0)

在select语句中,您必须为变量声明一个值。我把它变成了一个整数。如果是文本值,则可以使用varchar(25)。

@"DECLARE @EmployeeId INT

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