SQL:构建where子句

时间:2010-09-15 16:46:14

标签: sql sql-server sql-server-2005 tsql

有没有办法在sql语句中动态构建WHERE子句?

此代码位于存储过程中。我有x个参数,每个参数的默认值是NULL

SELECT *
FROM MyTable m
WHERE
   IF(NOT(@Param1 IS NULL))
     m.Col1 = @Param1
   END IF
AND
   IF(NOT(@Param2 IS NULL))
     m.Col2 = @Param2
   END IF

[编辑:]我正在运行SQL Server 2005。 [编辑:]参数的数量是固定的,但可以有一个NULL值。如果参数具有NULL值,则不应将其包含在WHERE子句中。每个参数也与特定列相关联。

4 个答案:

答案 0 :(得分:3)

这不等于以下,没有任何动态行为吗?

SELECT *
FROM MyTable m
WHERE
   (@Param1 IS NULL OR m.Col1 = @Param1)
AND
   (@Param2 IS NULL OR m.Col2 = @Param2)

或者列本身是否有可能丢失?

答案 1 :(得分:2)

假设SQL Server 2005+语法,因为未指定数据库...强烈建议在解决查询之前阅读:The curse and blessings of dynamic SQL

DECLARE @SQL NVARCHAR(4000)
    SET @SQL = N'SELECT m.*
                   FROM MyTable m
                  WHERE 1 = 1 '

    SET @SQL = @SQL + CASE 
                        WHEN @param1 IS NOT NULL THEN ' AND m.col1 = @param1 '
                        ELSE ' '
                      END   

    SET @SQL = @SQL + CASE 
                        WHEN @param2 IS NOT NULL THEN ' AND m.col2 = @param2 '
                        ELSE ' '
                      END

BEGIN

  EXEC sp_executesql @SQL,
                     N'@param1 [replace w/ data type], @param2 [replace w/ data type]'
                     @param1, @param2

END

答案 2 :(得分:0)

无论您是否使用存储过程,您都可能被迫使用动态sql。在实现这个存储过程之前,请考虑一些事情。

  1. 参数本身是动态的吗?你会使用2个参数一个呼叫,10个是下一个吗?如果是这种情况,您将需要创建大量“占位符”存储的proc参数,这些参数可能不会在每次调用时使用。如果定义10个占位符参数然后需要11,该怎么办?这不干净。也许你可以使用某种数组参数....

  2. 如果参数是动态的,您将被迫在proc中使用动态SQL。这可以让您了解注入攻击。您必须手动转义存储过程中的所有输入。在proc中使用dymamaic sql会破坏使用procs的主要原因之一。

  3. 如果参数是真正动态的,我实际上可能倾向于从代码而不是存储的proc生成sql。为什么?如果从代码生成,则可以使用ADO库来转义输入。

    确保你做的事情......

    sql =“select * from table where colA = @colA”; // dyanmically生成 SQlCommand.Parameters.add(“@ colA”,valueA);

    而不是....

    sql =“select * from table where colA =”+ valueA; // dyanmically生成错误的方式

答案 3 :(得分:0)

还要考虑第三件事。如果参数的数据类型是动态的,该怎么办?存储过程开始分崩离析,因为它们是已定义的接口。如果您的操作不符合接口,那么尝试将它们压缩到预先设置的界面将会很难看。

如果您正在制作某种开放式图形查询工具,则会弹出这种情况。大多数情况下,您的数据访问将符合某个界面,但是当它不符合时......存储过程可能不是最佳选择。