用于从连接表中进行选择的 T-SQL 查询,其中有可变数量的参数?

Posted

技术标签:

【中文标题】用于从连接表中进行选择的 T-SQL 查询,其中有可变数量的参数?【英文标题】:T-SQL query to for selecting from joined tables, where there's a variable number of parameters? 【发布时间】:2021-01-09 03:44:28 【问题描述】:

(我使用的是带有实体框架的 MS SQL Server,尽管 EF 只是执行一些原始 SQL)。

我需要从一些连接的表中检索一堆数据,但仅限于“employeeId”和“companyId”的特定组合(两者都是唯一性所必需的)。我的问题是,我不知道如何将这两个参数的列表传递到 SQL 查询中。

这是我的代码。这不完全是我所拥有的,但它是我正在尝试做的一个很好的模型。

public IEnumerable<MyDbo> GetWorkLocations(IEnumerable<EmployeeAndCompanyIdPair> employees)

  // These are commented out because they'll only grab the data for the first employee. 
  // They're mainly included as an example.
  //
  // var companyIdParam = new SqlParameter("@companyIdParam", SqlDbType.VarChar, 9)  Value = employees.First().CompanyId ;
  // var employeeIdParam = new SqlParameter("@employeeIdParam", SqlDbType.VarChar, 9)  Value = employees.First().EmployeeId ;

  var results = _dbContext.Database.SqlQuery<MyDbo>(@"
    SELECT 
        e.CompanyId
        e.EmployeeId
        w.WorkAddress
    FROM EmpInfo e
    INNER JOIN WorkLocation w on e.WorkLocationId = w.WorkLocationId
    WHERE
        e.CompanyId = @companyIdParam
        e.EmployeeId = @employeeIdParam
  ").ToList();
  
  return results;


// model used for the param above
public class EmployeeAndCompanyIdPair

    public string CompanyId  get; set; 
    public string EmployeeId  get; set; 

举个例子,我可能想将一个列表传递给上面的方法,如下所示:

CompanyId: "P555", EmployeeId: "12345",
CompanyId: "P555", EmployeeId: "12346",
CompanyId: "P555", EmployeeId: "12347",
CompanyId: "P777", EmployeeId: "54321",
CompanyId: "P777", EmployeeId: "54322"

我怎样才能使 SQL 查询可以接受这样的可变数量的两个参数?

【问题讨论】:

【参考方案1】:

所以你只需要枚举你的employees 并构建一个动态查询,例如像这样:

public IEnumerable<MyDbo> GetWorkLocations(IEnumerable<EmployeeAndCompanyIdPair> employees)

  var query = new StringBuilder();
  query.Append(@"
    SELECT 
        e.CompanyId
        e.EmployeeId
        w.WorkAddress
    FROM EmpInfo e
    INNER JOIN WorkLocation w on e.WorkLocationId = w.WorkLocationId
    WHERE

");

  var parameters = new List<SqlParameter>();
  var employeesArray = employees.ToArray();
  var count = employees.Length;
  for(var i = 0; i < count; i++) 
    query.AppendLine($"(e.CompanyId = @companyIdParami AND e.EmployeeId = @employeeIdParami)");

    if (i != count-1) 
        query.AppendLine(" OR ");
    

    parameters.Add(new SqlParameter($"@companyIdParami", SqlDbType.VarChar, 9)  Value = employeesArray[i].CompanyId );

    parameters.Add(new SqlParameter($"@employeeIdParami", SqlDbType.VarChar, 9)  Value = employeesArray[i].EmployeeId );
  

  var results = _dbContext.Database.SqlQuery<MyDbo>(query.ToString(), parameters.ToArray()).ToList();
  
  return results;

【讨论】:

哦,所以我可以动态地创建包含所有参数的查询,而不是只尝试一个万能的查询。太精彩了!我试试看,谢谢。 真的应该做点什么来处理employees为空的情况。 更好的是,与其在运行时构建非常大的查询并耗尽您的执行计划缓存 - 将您的值插入临时表(或“工作”表)并加入该表。跨度>

以上是关于用于从连接表中进行选择的 T-SQL 查询,其中有可变数量的参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 T-SQL 中的表中选择前 N 行?

T-SQL 子查询 Max(Date) 和连接

T-SQL:如何在值列表中选择不在表中的值?

sql 从视图和表中选择

T-SQL - 如何编写条件连接

如何进行 T-SQL 查询,其中输出的第一个字母等于一个字符