SQL Server如果语句失败

时间:2010-01-08 20:30:21

标签: sql-server sql-server-2008 stored-procedures if-statement

我在使用以下菜单时遇到了一些问题

Create PROCEDURE GetMatchingUsers
@id int = NULL,
@lastName varchar(50) = NULL,
@firstName varchar(50) = NULL
AS
BEGIN

 SET NOCOUNT ON

 DECLARE @q nvarchar(4000),
 @paramlist  nvarchar(4000)  

    SELECT @q = 'SELECT Id
  , LastName
  , FirstName '
 SELECT @q = @q + 'FROM Users WHERE 1 = 1' 

 IF ISNULL(@id, '')  <> ''                                 
  SELECT @q = @q + ' AND Id = ' + Cast(@id as varchar)
 IF ISNULL(@lastName, '')  <> ''                                           
  SELECT @q = @q + ' AND LastName like ''' + @lastName + '%''' 
 IF ISNULL(@firstName, '')  <> ''                                           
  SELECT @q = @q + ' AND FirstName like ''' + @firstName + '%'''   

 SELECT @q = @q + ' ORDER BY LastName, FirstName '

 --PRINT @q

 SELECT @paramlist = '
  @id int = NULL,
  @lastName varchar(50) = NULL,
  @firstName varchar(50) = NULL'

 EXEC sp_executesql @q, @paramlist,                               
   @id,
   @lastName,
   @firstName

我很奇怪为什么如果我将0作为id

传递,则以下if语句不被视为true
IF ISNULL(@id, '')  <> ''                                 
    SELECT @q = @q + ' AND Id = ' + Cast(@id as varchar)

感谢您的帮助

4 个答案:

答案 0 :(得分:3)

declare @id int 
set @id = 0     
if isnull(@id, '') = ''  
  print 'true'

这不应该让任何人感到惊讶,它都记录在产品规格中:

  • ISNULL被记录为返回已检查表达式的类型,而不是替换表达式。因此isnull(@id, '')将返回0作为类型int
  • 比较if 0=''将遵循Data Type Precedence的规则并转换为更高的优先级类型,在本例中为int
  • 字符串''转换为int值,相当于cast('' as int),为0.

因此,比较与编写if 0=0非常相似,当然,这是正确的。 q.e.d。

答案 1 :(得分:2)

零与NULL不同。 Null或多或少没有任何价值。零是一个价值。

如果你希望0是一个值,你可以传递它的工作方式就像你传入NULL一样(即如果你给它0,不要做选择)然后这样做:

IF ISNULL(@id, 0)  <> 0                                 
    SELECT @q = @q + ' AND Id = ' + Cast(@id as varchar)

答案 2 :(得分:2)

这很奇怪 - 它可能与你混合int和字符串文字这一事实有关。根据您的要求,if @id is nullif @id is not null似乎更直接

我用一个简单的例子重现了这一点(我将<>更改为=以使逻辑更加明显):

declare @id int
set @id = 0

if isnull(@id, '') = '' 
  print 'true'
else
  print 'false'

您希望这会打印'false',但会打印'true'。如果将@id的值设置为1,则它将按预期运行。

答案 3 :(得分:0)

NULL表示未知,不是零。所以

IF @id&gt; 0

应该有效。但我会远离构建字符串并将其重写为:

SELECT Id 
  , LastName 
  , FirstName 
FROM Users
WHERE id = @id or
(@lastName is null or LastName like @lastName+'%') or
(@firstName is null or FirstName like @firstName+'%') 
ORDER BY LastName, FirstName 

以下是相同的,但较少自我记录。

SELECT Id 
  , LastName 
  , FirstName 
FROM Users
WHERE id = @id or
LastName like @lastName+'%' or
FirstName like @firstName+'%' 
ORDER BY LastName, FirstName