我在SQL Server中有一个存储过程,它接受3个参数并返回如下的Orders列表:
@fieldToFilter VARCHAR(100), --Will only be 1 of these values 'Order Date', 'Delivery Date' or 'Dispatch Date'
@StartDate DATE,
@EndDate DATE
SELECT
o.Number, o.Customer
FROM
Order o
WHERE
(o.OrderDate > @StartDate)
AND (o.OrderDate < @EndDate)
AND (SoftDeleted = 0)
上面的查询存在的问题是我在OrderDate
子句中对列WHERE
进行了硬编码。
我想要做的是使用@fieldToFilter
中的值来确定应该过滤哪个列。例如
@fieldToFilter
为Order Date
,请过滤OrderDate
列@fieldToFilter
为Delivery Date
,则过滤DeliveryDate
列@fieldToFilter
为Dispatch Date
,则过滤DispatchDate
列实现这样的最佳方法是什么?
答案 0 :(得分:1)
这应该让你开始。只需用适当的过滤器替换另外两个SELECT语句。
IF @fieldToFilter = 'Order Date'
BEGIN
SELECT o.Number, o.Customer
FROM Order o
WHERE (o.OrderDate > @StartDate) and (o.OrderDate < @EndDate) and SoftDeleted=0)
END
ELSE IF @fieldToFilter = 'Delivery Date'
BEGIN
SELECT '2'
END
ELSE IF @fieldToFilter = 'Dispatch Date'
BEGIN
SELECT '3'
END
答案 1 :(得分:1)
我不确定我的语法是否正确,但这样的事情应该有效
SELECT o.Number, o.Customer
FROM Order o
WHERE (@StartDate < case when @fieldToFilter = 'Order Date' then o.OrderDate
when @fieldToFilter = 'Delivery Date' then o.DeliveryDate
when @fieldToFilter = 'Dispatch Date' then o.DispatchDate
else o.OrderDate end)
and (@EndDate > case when @fieldToFilter = 'Order Date' then o.OrderDate
when @fieldToFilter = 'Delivery Date' then o.DeliveryDate
when @fieldToFilter = 'Dispatch Date' then o.DispatchDate
else o.OrderDate end)
and (SoftDeleted=0)
答案 2 :(得分:0)
有两种可能的方法。
1 - 将列名传递给过程并动态构建查询。
CREATE PROCEDURE Get_Data
@fieldToFilter SYSNAME --Will only be 1 of these values 'Order Date', 'Delivery Date' or 'Dispatch Date'
,@StartDate DATE
,@EndDate DATE
AS
BEGIN
SET NOCOUNT ON;
Declare @Sql NVARCHAR(MAX);
SET @Sql = N' SELECT o.Number, o.Customer
FROM [Order] o
WHERE (o.'+QUOTENAME(@fieldToFilter)+' > @StartDate)
and (o.'+QUOTENAME(@fieldToFilter)+' < @EndDate)
and (SoftDeleted=0) '
Exec sp_executesql @Sql
,N'@StartDate DATE, @EndDate DATE'
,@StartDate
,@EndDate
END
2 - 您为每个列添加参数,为要应用的过滤器将值设置为1,这也为您提供了应用多个过滤器或根本不应用的选项。
CREATE PROCEDURE Get_Data
@FilterOnOrderDate BIT = NULL
,@FilterOnDeliveryDate BIT = NULL
,@FilterOnDispatchDate BIT = NULL
,@StartDate DATE = NULL
,@EndDate DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
Declare @Sql NVARCHAR(MAX);
SET @Sql = N' SELECT o.Number, o.Customer
FROM [Order] o
WHERE (SoftDeleted=0) '
+ CASE WHEN @FilterOnOrderDate = 1 THEN
N' AND (o.OrderDate > @StartDate)
AND (o.OrderDate < @EndDate) ' ELSE N'' END
+ CASE WHEN @FilterOnDeliveryDate = 1 THEN
N' AND (o.DeliveryDate > @StartDate)
AND (o.DeliveryDate < @EndDate) ' ELSE N'' END
+ CASE WHEN @FilterOnDispatchDate = 1 THEN
N' AND (o.DispatchDate > @StartDate)
AND (o.DispatchDate < @EndDate) ' ELSE N'' END
Exec sp_executesql @Sql
,N'@StartDate DATE, @EndDate DATE'
,@StartDate
,@EndDate
END
答案 3 :(得分:0)
请使用以下内容帮助您
DECLARE @sql nvarchar(max) = ''
SET @sql = @sql + 'SELECT
o.Number, o.Customer
FROM
Order o
WHERE (SoftDeleted = 0) '
if @fieldToFilter = 'Order Date'
begin
SET @sql = @sql + 'AND (o.OrderDate > @StartDate) AND (o.OrderDate < @EndDate)'
end
else if @fieldToFilter = 'Delivery Date'
begin
SET @sql = @sql + 'AND (o.DeliveryDate > @StartDate) AND (o.DeliveryDate < @EndDate)'
end
else if @fieldToFilter = 'Dispatch Date'
begin
SET @sql = @sql + 'AND (o.DispatchDate > @StartDate) AND (o.DispatchDate < @EndDate)'
end
exec (@sql)