SQL - 创建具有多个可选参数的存储过程

Posted

技术标签:

【中文标题】SQL - 创建具有多个可选参数的存储过程【英文标题】:SQL - Creating a stored procedure with multiple optional parameters 【发布时间】:2014-12-05 11:12:58 【问题描述】:

我正在尝试在存储过程 (SQL Server 2012) 中创建可选参数,这将允许用户选择以下内容。

参考编号范围 - 包含在表 2 中 - (可选)

客户编号范围 - 保留在表 3 中 -(可选)

日期范围 - 保留在表 4 中 - (强制)

必须输入参考编号或客户编号

到目前为止我有这个

declare @RefFrom Varchar(50) = NULL --'F51'  
declare @RefTo Varchar(50) = NULL --'F51' 
declare @CustomerNumFrom Varchar(50) = NULL --'FH1' 
declare @CustomerNumTo Varchar(50) = NULL --'FH1'
declare @fromDate date -- Works for date ranges 
declare @toDate date

set @fromDate = '2014-10-01'
set @toDate = '2014-11-05'

set @toDate  = IIF(@toDate  is NULL,  @toDate , DATEADD(day,1,@toDate ))
set @toDate  = IIF(@toDate  is NULL,  @fromeDate, @toDate )

SELECT 

Table2.Ref AS [Ref],
Table3.Number AS [Customer Number],
Table4.FromDate AS [Date],
Table4.ToTime AS [Time],



FROM Table1 
INNER JOIN Table2 ON Table1.ID = Table2.ID 
INNER JOIN Table3 ON Table2.ID = Table3.ID 
INNER JOIN Table5 ON Table1.DatID = Table5.ID 
INNER JOIN Table4 ON Table5.ID = Table4.ID 

where Table1.StatID = 1

AND Table4.ID
IN (    
        select Table4.ID 
        from Table4
        where 
            (
                CONVERT(DATETIME, CONVERT(CHAR(8), Table4.Date, 112) + ' ' + CONVERT(CHAR(8), Table4.Time, 108)) >=  @fromDate
                AND
                CONVERT(DATETIME, CONVERT(CHAR(8), Table4.Date, 112) + ' ' + CONVERT(CHAR(8), Table4.Time, 108)) <= @toDate
            )
            AND

            Table4.Info = 1

            AND

            (
                (Table2.Ref >= @RefFrom) OR (@RefFrom IS NULL)
                AND
                (Table2.Ref <= @RefTo) OR (@RefTo IS NULL)
            )

            AND   

            (
                (Table3.Number >= @CustomerNumFrom) OR (@CustomerNumFrom IS NULL)
                AND
                (Table3.Number <= @CustomerNumTo) OR (@CustomerNumTo IS NULL)
                )   
            )

目前遇到了一些问题。

首先不起作用的是我可以在 Reference 和 CustomerNumber 中都有空值,我仍然会根据日期范围返回数据,

第二件事不起作用的是,当我输入 CustomerNumber 范围时,它会返回指定范围之外的 CustomerNumers。

如果有人可以提供帮助,我真的很想解决这个问题

谢谢

【问题讨论】:

【参考方案1】:

首先不起作用的是我可以在 Reference 和 CustomerNumber 中都有空值,我仍然会根据日期范围返回数据,

请澄清这一点 - 您想要这种行为,还是这种行为发生并且不可取?

第二个不起作用的是,当我输入 CustomerNumber 范围时,它会返回指定范围之外的 CustomerNumers。

您的 AND / OR 优先级不正确。在 AND 之前将 OR 括起来:

(Table3.Number >= @CustomerNumFrom OR @CustomerNumFrom IS NULL)
AND
(Table3.Number <= @CustomerNumTo OR @CustomerNumTo IS NULL)   

但是请注意,比较仅适用于客户编号上的固定位数,例如比较 F51F51111 不会有好的结果。

还有一点 - 在 where 子句中像这样执行 CONVERT 会损害性能(SARGability)。数据模型中将日期和时间分开,这似乎很奇怪——如果将日期和时间合并为一列,可以直接进行日期时间比较?

【讨论】:

您好,为您的回答干杯,我现在已经完成了第二部分。 对于第一部分,如果用户没有输入参考编号和客户编号,则不应返回任何数据。用户必须输入这些选项中的至少一个,所以它目前正在做的事情是不可取的! 感谢您对 CONVERT 的看法,我会看看其他选项以及日期时间比较 :) 我现在也整理出了第一部分,我会尽快发布我的解决方案。 Apols - 我已经 AFK 了几个小时 - 很高兴你解决了!

以上是关于SQL - 创建具有多个可选参数的存储过程的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JavaScript 创建具有多个可选参数的搜索?

我可以在存储过程中有一个可选的 OUTPUT 参数吗?

where 条件中的可选参数 - 如何提高性能 - PL/SQL

创建存储过程

spring 将可选查询参数映射到 sql 准备语句

数据库存储过程和触发器