1

我遇到一些麻烦,下面的存储过程SQL服务器如果语句愁楚

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 ISNULL(@id, '') <> ''         
    SELECT @q = @q + ' AND Id = ' + Cast(@id as varchar) 
声明不被认为是真正的

感谢您的帮助

回答

2

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

我转载此用一个简单的例子(我改变<>=,使逻辑有点更明显):

declare @id int 
set @id = 0 

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

你会期望这打印'假',但它打印'真'。如果将@id的值设置为1,则其行为与预期相同。

2

零与NULL不是一回事。空或多或少没有任何价值。零是一个价值。

如果你想0是,你可以通过它的工作一样,如果你曾在NULL传递(即,如果你给它0,不要做选择)的值,那么做到这一点:

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

我真的希望它连接字符串,如果传入的ID是0. 我不希望它进入该块的唯一时间是如果该ID根本没有传入。 – AlteredConcept

+0

然后将上面的0改为-1(即:ISNULL(@ Id,-1)<> -1 –

0

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

IF @id> 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 
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,这是当然的,真实的。证明完毕