我在使用以下菜单时遇到了一些问题
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语句不被视为trueIF ISNULL(@id, '') <> ''
SELECT @q = @q + ' AND Id = ' + Cast(@id as varchar)
感谢您的帮助
答案 0 :(得分:3)
declare @id int
set @id = 0
if isnull(@id, '') = ''
print 'true'
这不应该让任何人感到惊讶,它都记录在产品规格中:
isnull(@id, '')
将返回0作为类型int
。 if 0=''
将遵循Data Type Precedence的规则并转换为更高的优先级类型,在本例中为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 null
或if @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