有条件地过滤由变量值确定的结果

时间:2016-05-12 16:40:42

标签: tsql sql-server-2012 sql-server-2008-r2

我有一种情况,即2个变量从外部系统传递到查询中。

如果变量为0,则表示不使用它进行过滤。

这样的事情:

--if @a = 0 then don't filter by @a
--if @b = 0 then don't filter by @b

SELECT * FROM Engines e
JOIN Transmissions t ON e.carId = t.carId
WHERE e.engineId IN(@a)
AND t.transmissionId IN (@b)

因此,例如,如果@a为0,则只担心过滤传输。查询基本上是:

SELECT * FROM Engines e
JOIN Transmissions t ON e.carId = t.carId
WHERE t.transmissionId IN (@b)

或者如果@b为0,那么它会是这样的:

SELECT * FROM Engines e
JOIN Transmissions t ON e.carId = t.carId
WHERE e.engineId IN(@a)

或者如果@a和@b均为0,则显示如下所示:

SELECT * FROM tblA a
JOIN tblB b ON a.carId = b.carId

有没有办法像这样有条件地过滤?

由于

4 个答案:

答案 0 :(得分:1)

假设:@a和@b都有默认值0。

这应该这样做:

--if @a = 0 then don't filter by @a
--if @b = 0 then don't filter by @b

SELECT * FROM Engines e
JOIN Transmissions t ON e.carId = t.carId
WHERE (@a = 0 OR e.engineId IN(@a))
      AND (@b = 0 OR t.transmissionId IN (@b))

答案 1 :(得分:1)

试试这个:

CREATE TABLE #Engines
    (
      engineId INT
    , EngineName CHAR(5)
    , carId INT
    );
CREATE TABLE #Transmissions
    (
      transmissionId INT
    , Transmitter CHAR(5)
    , carId INT
    );
INSERT  INTO #Engines
        ( engineId, EngineName, carId )
VALUES  ( 0, 'a', 10 ),
        ( 1, 'b', 20 ),
        ( 2, 'c', 30 ),
        ( 3, 'd', 40 ),
        ( 4, 'e', 50 );

INSERT  INTO #Transmissions
        ( transmissionId, Transmitter, carId )
VALUES  ( 0, 'aa', 10 ),
        ( 1, 'bb', 20 ),
        ( 2, 'cc', 30 ),
        ( 3, 'dd', 40 ),
        ( 4, 'ee', 60 );

DECLARE @a INT= 4
  , @b INT= 0;

DECLARE @where VARCHAR(MAX)
  , @sql VARCHAR(MAX);
SET @where = ( SELECT   CASE WHEN @a = 0
                                  AND @b <> 0
                             THEN '1=1 and t.transmissionId IN ( @b )'
                             WHEN @b = 0
                                  AND @a <> 0
                             THEN '1=1 and e.engineId IN ( @a )'
                             ELSE '1=1'
                        END
             );
--SELECT  @where;
SET @sql = 'SELECT  e.engineId
      , e.EngineName
      , e.carId
      , t.transmissionId
      , t.Transmitter
      , t.carId
FROM    #Engines e
        JOIN #Transmissions t
        ON e.carId = t.carId
WHERE ';
--SELECT  @sql;
DECLARE @FinalSql VARCHAR(MAX) = 'DECLARE @a INT=3
  , @b INT= 0; ' + @sql + @where;
--SELECT  @FinalSql;
--SELECT  @FinalSql;
EXECUTE(@FinalSql); 

答案 2 :(得分:1)

这肯定会对您有所帮助

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at CRLib.CollateralRequiredProcessor.Cr22(RCItem anItem)
   at CRLib.CollateralRequiredProcessor.CalculateRequiredCollateral(RCItem anItem)
   at CRLib.CollateralRequiredProcessor.Process(String server, String user, String pass, String database, String startDate, String endDate)
   at CRUI.frmMain.butProcess_Click(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

答案 3 :(得分:1)

@Pankaj Kumar:它有效,但代码中存在语法错误。我无法添加评论,因此将其添加为其他答案:

{{1}}