2016-05-20 79 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) 
相關問題