2016-05-20 49 views
0

我在SQL Server中这需要3个参数,并返回类似这样的订单列表的存储过程:SQL查询的字段名称传递到存储过程

@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) 

上面的查询的问题是,我有对WHERE子句中的列OrderDate进行了硬编码。

我想要做的是使用@fieldToFilter中的值来确定应过滤哪个列。例如

  • 如果@fieldToFilterOrder Date然后在OrderDate列过滤
  • 如果@fieldToFilterDelivery Date然后在DeliveryDate列过滤
  • 如果@fieldToFilterDispatch Date然后在DispatchDate列过滤

会是什么是实现这样的事情的最佳方式吗?

+0

M2c构成 - 这里有根本的两种方法:一种是查询优化器可以优化和一个它不能....根据您的要求后者可能不被接受。我会问的问题是什么促使要求能够过滤通用字段?实现三个不同的查询(不管你觉得最易于管理)将提供最佳的优化机会。 –

回答

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) 
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 
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添加paramaeter,设定值要应用的过滤器,这也使您能够在所有应用多个过滤器或者根本没有选择。

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 
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) 
相关问题