Sql 在不同的搜索条件下创建具有不同WHERE子句的存储过程,而不将所有内容放入长字符串中

Sql 在不同的搜索条件下创建具有不同WHERE子句的存储过程,而不将所有内容放入长字符串中,sql,tsql,Sql,Tsql,若WWHERE子句的条件可能不同,是否有其他方法可以创建存储过程而不将所有查询放在一个长字符串中 假设我有一个Orders表,我想在这个表上创建存储过程,并且有三列我需要在其中筛选记录 1-客户ID,2-供应商ID,3-产品ID 若用户只在搜索条件中提供CustomerId,那个么查询应该如下所示 SELECT * FROM Orders WHERE Orders.CustomerId = @customerId SELECT * FROM Orders WHERE Orders.Produc

若WWHERE子句的条件可能不同,是否有其他方法可以创建存储过程而不将所有查询放在一个长字符串中

假设我有一个Orders表,我想在这个表上创建存储过程,并且有三列我需要在其中筛选记录

1-客户ID,2-供应商ID,3-产品ID

若用户只在搜索条件中提供CustomerId,那个么查询应该如下所示

SELECT * FROM Orders WHERE Orders.CustomerId = @customerId
SELECT * FROM Orders WHERE Orders.ProductId = @productId
SELCT * FROM Orders
若用户只在搜索条件中提供ProductId,那个么查询应该如下所示

SELECT * FROM Orders WHERE Orders.CustomerId = @customerId
SELECT * FROM Orders WHERE Orders.ProductId = @productId
SELCT * FROM Orders
如果用户只给出了所有三个CustomerId、ProductId和SupplierId,那么所有三个ID都将用于WHERE-to-filter

也有可能用户不想过滤记录,那个么查询应该如下所示

SELECT * FROM Orders WHERE Orders.CustomerId = @customerId
SELECT * FROM Orders WHERE Orders.ProductId = @productId
SELCT * FROM Orders
每当我必须创建此类过程时,我都将所有这些放在字符串中,并使用IF条件检查参数(@customeId或@supplierId等)是否有值

我使用以下方法创建过程

DECLARE @query      VARCHAR(MAX)
DECLARE @queryWhere VARCHAR(MAX)

SET @query = @query + 'SELECT * FROM Orders '

IF (@originationNumber IS NOT NULL)
BEGIN
    BEGIN
        SET @queryWhere =@queryWhere + ' Orders.CustomerId = ' + CONVERT(VARCHAR(100),@customerId)
    END
END

IF(@queryWhere <> '')
BEGIN
   SET @query = @query+' WHERE ' + @queryWhere
END

EXEC (@query)
DECLARE@query VARCHAR(最大值)
声明@queryWhere VARCHAR(最大值)
SET@query=@query+'SELECT*FROM Orders'
如果(@originationNumber不为空)
开始
开始
设置@queryWhere=@queryWhere+'Orders.CustomerId='+CONVERT(VARCHAR(100),@CustomerId)
结束
结束
如果(@queryWhere“”)
开始
设置@query=@query+'WHERE'+@queryWhere
结束
EXEC(@query)

谢谢。

对于不希望包含在
WHERE
-子句中的字段,您可以传递
NULL
,并在查询中检查
NULL

Select customerId, productId, supplierId
From Orders
Where ( customerId = @customerId Or @customerId IS NULL )
  And ( productId = @productId Or @productId IS NULL )
  And ( supplierId= @supplierId Or @supplierId IS NULL )

不要使用
SELECT*
,始终列出您实际需要的列。

Erland Sommarskog有一对很好的列表,描述了各种搜索技术和权衡(一个用于SQL 2008,一个用于早期版本)

如果您使用
ISNULL
,我不确定是否可以使用索引?我曾在存储过程中多次使用过它,用于处理具有数千行的表,并且索引没有问题,但我从未运行过执行计划以查看索引是否工作。这是一个很好的评论,我将运行一些执行计划来了解Oracle(
NVL
COALESCE
)发生了什么,但没有使用索引。请运行您的测试,并让我们知道TSQL是否对
ISNULL
@PeterLang进行了某种特殊优化。您完全正确。我创建了一个包含int ID和两个nvarchar列的表。在一个nvarchar列上,我创建了一个索引,但该索引没有启动。我还发现,为什么我使用ISNULL没有问题。当您在MSSQL 2005中的表中创建PK时,它将创建聚集索引;当您在使用此聚集索引的位置使用ISNULL时,它将创建聚集索引。感谢您的尝试。我认为最好使用
而不是
ISNULL
来允许使用索引:
Select CustomerId, ProductId, SupplierId
From Orders
Where CustomerId = ISNULL( @customerId, CustomerId   )
  And ProductId = ISNULL( @productId, ProductId  )
  And SupplierId= ISNULL( @supplierId, SupplierId )