当没有参数传递给函数时,带有参数的sql server存储过程返回所有记录

时间:2016-11-22 13:00:23

标签: sql-server tsql stored-procedures

我有SQL服务器存储过程我希望它在没有参数传递给它时返回所有记录,我测试程序它返回所有记录,当我删除min和max参数构建它然后执行它。

alter PROCEDURE SearchBYProjects
@location NVARCHAR(50),
@purpose NVARCHAR(50),
@type NVARCHAR(50),
@min NVARCHAR(50),
@max NVARCHAR(50)
AS
SELECT 
    p.ID,
    p.ProjectName, 
    p.Areas, 
    p.PaymentSystem, 
    p.ReceivedDate,    
    p.PropertyClassification, 
    p.ProjectImage,         
    l.LocationName,
    Pur.PurposeName,            
    t.TypeName
 FROM dbo.Projects AS p 
 LEFT JOIN dbo.Locations AS l ON p.LocationID = l.ID      
 LEFT JOIN dbo.Purpose pur ON p.PurposeID = pur.ID 
 LEFT JOIN dbo.[Types] AS t ON p.TypeID = t.ID
 WHERE UPPER(ISNULL(l.LocationName,N'')) LIKE N'%' + UPPER(@location) + '%'
 AND UPPER(ISNULL(pur.PurposeName,N'')) LIKE N'%' + UPPER(@purpose) + '%'
 AND UPPER(ISNULL(t.TypeName,N'')) LIKE N'%' + UPPER(@type) + '%'
 AND  UPPER(ISNULL(p.Areas,'')) BETWEEN @min AND @max
 GO

 EXEC dbo.SearchBYProjects @location ='',@purpose='',@type='',@min='',@max=''

感谢任何帮助。

3 个答案:

答案 0 :(得分:2)

仅添加:

or coalesce(@location,@purpose,@type,@min,@max) is null

尽量不要在搜索的参数上使用函数。当您使用函数(ISNULL,COALESCE,UPPER,udf ..)时,您的参数不再是SARG。如果不是necasary,请不要使用'%dasda' - 对名称,位置,目的(或非结构化数据)使用全文搜索。

答案 1 :(得分:1)

也许这个:

alter PROCEDURE SearchBYProjects
    @location NVARCHAR(50) = null,
    @purpose NVARCHAR(50) = null,
    @type NVARCHAR(50) = null,
    @min NVARCHAR(50) = null,
    @max NVARCHAR(50) = null
AS
SELECT 
    p.ID,
    p.ProjectName, 
    p.Areas, 
    p.PaymentSystem, 
    p.ReceivedDate,    
    p.PropertyClassification, 
    p.ProjectImage,         
    l.LocationName,
    Pur.PurposeName,            
    t.TypeName
 FROM dbo.Projects AS p 
 LEFT JOIN dbo.Locations AS l ON p.LocationID = l.ID      
 LEFT JOIN dbo.Purpose pur ON p.PurposeID = pur.ID 
 LEFT JOIN dbo.[Types] AS t ON p.TypeID = t.ID
 WHERE (@location is null or UPPER(ISNULL(l.LocationName,N'')) LIKE N'%' + UPPER(@location) + '%')
 AND (@purpose is null or UPPER(ISNULL(pur.PurposeName,N'')) LIKE N'%' + UPPER(@purpose) + '%')
 AND (@type is null or UPPER(ISNULL(t.TypeName,N'')) LIKE N'%' + UPPER(@type) + '%')
 AND (@min is null or UPPER(ISNULL(p.Areas,'')) >= @min)
 AND (@max is null or UPPER(ISNULL(p.Areas,'')) <= @max)
 GO

 EXEC dbo.SearchBYProjects 

请注意,这种方式也可以让你传递一些空值,而不是其他的

EXEC dbo.SearchBYProjects @type='SomeType' 

将返回type =&#39; SomeType&#39;

的所有内容

值得一提的是,如果&#34;地区&#34;是一个字符串,这可能不会按预期行事,例如&#39; 110&#39;来自&#39; 2&#39;以及&#39; 10&#39;和&#39; 20&#39;。因此,如果这些是数字,那么您可能希望在where子句中转换它们。

答案 2 :(得分:1)

同样Sean和Deadsheep39所说的一切。为了扩展deadsheep39所说的内容,你的WHERE子句可能如下所示:

WHERE 
( 
      UPPER(ISNULL(l.LocationName,N'')) LIKE N'%' + UPPER(@location) + '%'
  AND UPPER(ISNULL(pur.PurposeName,N'')) LIKE N'%' + UPPER(@purpose) + '%'
  AND UPPER(ISNULL(t.TypeName,N'')) LIKE N'%' + UPPER(@type) + '%'
  AND UPPER(ISNULL(p.Areas,'')) BETWEEN @min AND @max
)
OR COALESCE(@location,@purpose,@type,@min,@max) IS NULL;

如果你走这条路,请务必查看Sean发布的文章。

因为你在存储过程中这样做,你也可以在proc中处理这个要求(这就是我的方法):

IF COALESCE(@location,@purpose,@type,@min,@max) IS NULL
  SELECT 
     p.ID,
     p.ProjectName, 
     p.Areas, 
     p.PaymentSystem, 
     p.ReceivedDate,    
     p.PropertyClassification, 
     p.ProjectImage,         
     l.LocationName,
     Pur.PurposeName,            
     t.TypeName
  FROM dbo.Projects AS p 
  LEFT JOIN dbo.Locations AS l ON p.LocationID = l.ID      
  LEFT JOIN dbo.Purpose pur ON p.PurposeID = pur.ID 
  LEFT JOIN dbo.[Types] AS t ON p.TypeID = t.ID
ELSE
  SELECT 
     p.ID,
     p.ProjectName, 
     p.Areas, 
     p.PaymentSystem, 
     p.ReceivedDate,    
     p.PropertyClassification, 
     p.ProjectImage,         
     l.LocationName,
     Pur.PurposeName,            
     t.TypeName
  FROM dbo.Projects AS p 
  LEFT JOIN dbo.Locations AS l ON p.LocationID = l.ID      
  LEFT JOIN dbo.Purpose pur ON p.PurposeID = pur.ID 
  LEFT JOIN dbo.[Types] AS t ON p.TypeID = t.ID
  WHERE l.LocationName LIKE N'%' + @location + '%'
  AND pur.PurposeName LIKE N'%' + @purpose + '%'
  AND t.TypeName,N'')) LIKE N'%' @type + '%'
  AND  p.Areas BETWEEN @min AND @max;

然后,在执行proc时,您总是希望进行重新编译。 E.g:

EXECUTE <your proc> WITH RECOMPILE;