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,這是當然的,真實的。證明完畢