0

我正在尝试进行执行以下操作的查询:我的 Items 数据库中有列,这些列称为 Title、AuthorName 和 ItemType。我想在查询中执行以下操作:用户输入 AuthorName、Title 并从下拉列表中选择 ItemType。用户可以将 AuthorName 或 Title 框留空。例如,即使他没有填写 AuthorName 部分,如果找到具有指定 ItemType 和指定 Title 的项目,我也会在结果中显示它。同样,Title 可以留空,在这种情况下,具有指定 AuthorName 的项目会列在结果列表中。这是我的查询:

SELECT  *
FROM    [Items]
WHERE   ( ( ( [Title] LIKE '%' + @Title + '%' )
            AND ( [ItemType] = @ItemType )
          )
          OR ( ( [AuthorName] LIKE '%' + @AuthorName + '%' )
               AND ( [ItemType] = @ItemType )
             )
        )

但是当 AuthorName 或 Title 为空时,找不到任何结果。任何人都可以帮忙吗?

谢谢

4

4 回答 4

2
Select ...
From Items
Where ( @Title Is Null Or Title Like '%' + @Title + '%' )
    And ( @AuthorName Is Null Or AuthorName Like '%' + @AuthorName + '%' )
    And ItemType = @ItemType

在 ASP.NET 中,您应该检查表单值string.IsNullOrEmpty,如果为真,则发送DBNull.Value到参数化查询而不是空字符串。

如果您坚持为您的参数传递一个空字符串(这不是首选),那么查询需要检查空字符串:

Select ...
From Items
Where ( Len(@Title) = 0 Or Title Like '%' + @Title + '%' )
    And ( Len(@AuthorName) = 0 Or AuthorName Like '%' + @AuthorName + '%' )
    And ItemType = @ItemType

在 SQL Server 中,该Len函数将忽略空格。如果您真的想发疯并在查询中进行所有检查(同样不建议这样做),那么您可能需要考虑您的参数是空字符串、所有空格或空值:

Select ...
From Items
Where ( Len(Coalesce(@Title,'')) = 0 Or Title Like '%' + @Title + '%' )
    And ( Len(Coalesce(@AuthorName,'')) = 0 Or AuthorName Like '%' + @AuthorName + '%' )
    And ItemType = @ItemType
于 2013-05-30T15:09:45.967 回答
1

尝试这样的事情:

SELECT  *
FROM    [Items]
WHERE   ([ItemType] = @ItemType)
        AND ([Title] LIKE '%' + @Title + '%' OR @Title IS NULL)
        AND ([AuthorName] LIKE '%' + @AuthorName + '%' OR @AuthorName IS NULL)

只要确保在or为空NULL时传入值 (System.DBNull.Value) 。AuthorNameTitle

更新

假设AuthorName和在“未选中”时作为空字符串传递给您的代码隐藏,Title您可以执行以下操作(字符串在哪里传递给您的代码隐藏):authorNametitle

VB:

cmd.Parameters.Add("AuthorName", SqlDbType.VarChar, 50).Value = IIf(authorName.length > 0, authorName, System.DBNull.Value)
cmd.Parameters.Add("Title", SqlDbType.VarChar, 50).Value = IIf(title.length > 0, title, System.DBNull.Value)

C#:

cmd.Parameters.Add("AuthorName", SqlDbType.VarChar, 50).Value = (authorName.length > 0 ? authorName : System.DBNull.Value);
cmd.Parameters.Add("Title", SqlDbType.VarChar, 50).Value = (title.length > 0 ? title : System.DBNull.Value);
于 2013-05-30T15:11:40.043 回答
1

我在code.scottshipp.com的代码博客中写了一个完整的教程。可以下载该教程中的完整代码。它展示了如何将其设置为存储过程,还详细介绍了如何在查询中构造 where 子句。所以它涵盖了这两种情况。不过,您可能更容易走存储过程路线,因此您可能想读一读。

要记住的是,有多种方法可以做到这一点,但如果您使用 ISNULL 函数之类的东西,也有一些“陷阱”会使您的代码在某些情况下似乎有效,而在其他情况下则无效。

相反,一般来说,我会推荐以下内容:

将以下代码段添加到您希望有时为空白的 where 子句的任何部分:

    OR SomeParam IS NULL

此外,将括号括在整个内容周围有利于可读性。对您认为在某些时候可能为空白的每个参数执行此操作。例如,这意味着您的 select 语句将变为:

SELECT  *
FROM    [Items]
WHERE   ( ( ( [Title] LIKE '%' + @Title + '%' OR [Title] IS NULL )
        AND ( [ItemType] = @ItemType OR [ItemType] IS NULL )
      )
      OR ( ( [AuthorName] LIKE '%' + @AuthorName + '%' OR [AuthorName] IS NULL)
           AND ( [ItemType] = @ItemType OR [ItemType] IS NULL )
         )
    )
于 2013-05-30T15:20:12.733 回答
1

请试试这个

  SELECT  *
FROM    [Items]
WHERE   ( ( ( [Title] LIKE CASE WHEN ISNULL(@Title,'')='' THEN [Title] ELSE '%' + @Title + '%' END )
            AND ( [ItemType] = @ItemType )
          )
          OR ( ( [AuthorName] LIKE CASE ISNULL(@AuthorName,'')='' THEN [AuthorName] ELSE '%' + @AuthorName + '%' END)
               AND ( [ItemType] = @ItemType )
             )
        )

这会有所帮助。即使您没有通过 Title 或 Authorname,这也会运行。

于 2013-05-30T15:24:01.890 回答