【问题标题】:T-SQL stored proc conditionals in where clauseT-SQL 在 where 子句中存储 proc 条件
【发布时间】:2014-04-17 20:03:27
【问题描述】:

我正在尝试编写一个存储过程,其中 where 子句需要根据传递给过程的参数是动态的。

根据是否将空字符串传递给 StartDate 和 EndDate,ContractDate 条件选择行。如果它们是空字符串,则用户将传递一个日期列表(假设),我需要选择与列表中的 ContractDates 相同的行。如果 @StartDate 和 @EndDate 参数不是空字符串,我会选择 ContractDate >= @StartDate 和

select TermDescription,ContractDate,Price,SortOrder into #tbtp from BaseTermPrice 
inner hash join Term 
on 
Term.TermID = BaseTermPrice.TermID
where 
BaseID = @BaseID and PeakType = @PeakType and 
case when @StartDate != '' and @EndDate != '' 
then  
ContractDate >= @StartDate and ContractDate <= @EndDate
else
ContractDate in (@DateList)
end
order by 
ContractDate,SortOrder

【问题讨论】:

  • "string is passed to StartDate and EndDate" 为什么要对名为 StartDate 和 EndDate 的字段使用字符串?这是处理日期信息的一种糟糕的方式。
  • 是的。理想情况下,我想传递空值或实际日期。如何在 SQL 中将参数等同于 null。我习惯于容易等同于空值的编程语言。我对 SQL 比较陌生,无法弄清楚您如何将某些内容等同于 null?
  • 这取决于您使用的客户端语言和平台。
  • 我使用 C# 作为客户端语言,很容易传递空值。但是当调用存储过程时,我应该传递 DBNull 还是只传递 null?如何在 T-SQL 中验证 null 值?

标签: sql sql-server


【解决方案1】:

您应该研究动态 SQL。最好的起点是http://www.sommarskog.se/dynamic_sql.html。动态 SQL 允许您根据需要的任何条件以编程方式构建 SQL 字符串。

【讨论】:

    【解决方案2】:

    您也可以在没有动态 SQL 的情况下完成它。我不喜欢使用它来避免只会在运行时发现的语法错误。

    您需要将过程重组为仅包含完整 SQL 语句而不是片段的 IF 块。

    对于@DateList 变量:

    1. 将@DateList 变量解析为临时表#DateListTable。在此处查看最佳答案: How Do I Split a Delimited String in SQL Server Without Creating a Function?
    2. 将相关 SQL 更改为 ContractDate in (Select ContractDate from #DateListTable)

    【讨论】:

    • 这对于这个问题来说很好用,因为它的变量数量有限。当您需要检查大量条件时,动态 SQL 变得更加重要 - 您需要编写的字符串数量呈指数级增长。
    【解决方案3】:

    感谢您提出的所有宝贵建议。刚刚用 ands 和 ors 破解了这个

    select TermDescription,ContractDate,Price,SortOrder into #tbtp from BaseTermPrice 
    inner hash join Term 
    on 
    Term.TermID = BaseTermPrice.TermID
    where 
    BaseID = @BaseID and ((@PeakType IS NULL and PeakType is null) or (@PeakType IS NOT NULL and PeakType=@PeakType))
    and ((@DateList IS NULL and ContractDate between @StartDate and @EndDate) or (@StartDate IS NULL and ContractDate in (@DateList)))
    order by
    ContractDate,SortOrder
    

    【讨论】:

      猜你喜欢
      • 2011-05-28
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 2015-11-21
      相关资源
      最近更新 更多