必须在“选择”命令中声明标量变量

本文关键字:声明 标量 变量 命令 选择 | 更新日期: 2023-09-27 18:03:12

我将employeeid的长列表传递给employeeIdlist,并将它们拆分为list。使用此列表,我将参数添加到我的查询。我得到以下错误

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

必须在“选择”命令中声明标量变量

去掉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子句和匹配的参数列表运行命令

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

看起来你正在尝试应用这种方法,这是一个好主意。

你还差两行就能让它工作了:

添加以下行:

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

SqlDataReader rdr = getVersion.ExecuteReader();

添加的参数将匹配sql字符串中存在的@parameters

这只是另一个选项。您可以使用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();
        }
    }
}

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

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