2

此存储过程用于搜索记录。

当我只填写参数@IDor@FirstName时,它可以工作。但如果我只填写@LastName.

例如:

  • @ID = 1,其余的是NULL->应该给1行->结果:1​​行(好的)

  • @ID = NULL, @FirstName = 'Tim',其余的是NULL->应该给1行->结果:1​​行(好的)

  • @ID = NULL, @FirstName = NULL, @LastName = 'BlaBla',其余的是NULL --> 应该给出 1 行 --> 结果:所有行(不正常)

有谁知道为什么?

提前致谢。

这是我的程序:

ALTER PROCEDURE lookupSubscriber 
  -- Add the parameters for the stored procedure here
  @ID int,
  @firstname nvarchar(50), 
  @lastname nvarchar(60),
  @street nvarchar(80),
  @housenumber nvarchar(6),
  @companyname nvarchar(50),
  @city nvarchar(50),
  @ResultString nvarchar(80) OUTPUT,
  @ResultValue int OUTPUT,
  @ResultCount int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--Replacing empty strings with NULL
IF @ID = 0 BEGIN SET @ID = NULL; END
IF @firstname = '' BEGIN SET @firstname = NULL; END
IF @lastname = '' BEGIN SET @lastname = NULL; END
IF @street = '' BEGIN SET @street = NULL; END
IF @companyname = '' BEGIN SET @companyname = NULL; END
IF @housenumber = '' BEGIN SET @housenumber = NULL; END
IF @city = '' BEGIN SET @city = NULL; END

    -- Insert statements for procedure here
BEGIN TRY
    SELECT s.ID, COALESCE(d.FirstName,'NONE'), COALESCE(d.LastName,'NONE'), d.Street, COALESCE(d.CompanyName,'NONE'), d.HouseNumber, c.name
    FROM Subscriber s
    INNER JOIN SubscriberDetail d ON d.ID = s.Detail_ID
    INNER JOIN City c ON d.City_ID = c.ID
    WHERE (s.ID = COALESCE(@ID, s.ID)
        AND d.FirstName = COALESCE(@firstname, d.FirstName) OR d.FirstName = 'NONE'
        AND d.LastName = COALESCE(@lastname, d.LastName) OR d.LastName = 'NONE'
        AND d.Street = COALESCE(@street, d.Street)
        AND d.CompanyName = COALESCE(@companyname, d.CompanyName) OR d.CompanyName = 'NONE'
        AND d.HouseNumber = COALESCE(@housenumber, d.HouseNumber)
        AND c.name = COALESCE(@city, c.name))

    SET @ResultCount = @@ROWCOUNT
    SET @ResultString = 'Lookup successful'
    SET @ResultValue = 0
END TRY
BEGIN CATCH
    SET @ResultString = 'ERROR: ' + ERROR_MESSAGE()
    SET @ResultValue = 2
END CATCH
END
GO

示例数据:

订户:

ID = 1 | Type_ID = 1 | Detail_ID = 2

ID = 2 | Type_ID = 2 | Detail_ID = 3

订阅者详细信息:

ID = 1 | FirstName = 'Laurens' | LastName = 'De Neys' | CompanyName = NULL | Street = 'Ergens' | HouseNumber = 2 | City_ID = 1

ID = 2 | FirstName = 'Tim' | LastName = 'Blabla' | CompanyName = NULL | Street = 'Iets' | HouseNumber = 26 | City_ID = 2

城市:

ID = 1 | name = 'Liedekerke' | postalCode = 1770

ID = 1 | name = 'Leuven' | postalCode = 3000
4

2 回答 2

5

也许您需要将 OR 条件与原始条件放在括号中?

对于所有这些表达式:

AND d.LastName = COALESCE(@lastname, d.LastName) OR d.LastName = 'NONE'

改成

AND (d.LastName = COALESCE(@lastname, d.LastName) OR d.LastName = 'NONE')

编辑

好吧,我不知道您的数据库中有什么,但我感觉其中一些逻辑是不正确的。尝试这个:

SELECT s.ID, COALESCE(d.FirstName,'NONE'), COALESCE(d.LastName,'NONE'), d.Street, COALESCE(d.CompanyName,'NONE'), d.HouseNumber, c.name
    FROM Subscriber s
    INNER JOIN SubscriberDetail d ON d.ID = s.Detail_ID
    INNER JOIN City c ON d.City_ID = c.ID
    WHERE (@id is null or s.ID = @ID)
        AND (@firstname is null or d.FirstName = @firstname)
        AND (@lastname is null or d.LastName = @lastname)
        AND (@street is null or d.Street = @street)
        AND (@companyname is null or d.CompanyName = @companyname)
        AND (@housenumber is null or d.HouseNumber = @housenumber)
        AND (@city is null or c.name = @city)
于 2013-05-13T18:50:35.620 回答
4

您的WHERE陈述以这样一种方式安排了它的ANDOR条件,以至于他们对我假设您希望他们做的事情进行了错误的评估。您可以通过封装您的 OR 语句来解决它以说明正确的部分。例子:

WHERE (s.ID = COALESCE(@ID, s.ID)
    AND (d.FirstName = COALESCE(@firstname, d.FirstName) OR d.FirstName = 'NONE')
    AND (d.LastName = COALESCE(@lastname, d.LastName) OR d.LastName = 'NONE')
    AND d.Street = COALESCE(@street, d.Street)
    AND (d.CompanyName = COALESCE(@companyname, d.CompanyName) OR d.CompanyName = 'NONE')
    AND d.HouseNumber = COALESCE(@housenumber, d.HouseNumber)
    AND c.name = COALESCE(@city, c.name))

编辑:查看相同的数据,这里还有一个问题。您正在尝试检查公司名称与 COALESCE(@companyname, d.companyname) 的相等性,但在某些情况下您的 CompanyName 为 NULL。当一个值为 NULL 时,它是未知的,因此 SQL 不会将其视为相等,甚至与自身相等。

这是我通常更喜欢的原因之一,而不是COALESCE上面的语法来做这样的事情:

AND (@companyname IS NULL OR d.CompanyName = @companyname)

如果参数也为空(如果参数不为空,则您的相等性仍然有效),上述内容不关心公司名称的存储值是否为空。

于 2013-05-13T18:51:03.303 回答