使用ISNULL的SQL查询

本文关键字:查询 SQL ISNULL 使用 | 更新日期: 2023-09-27 17:58:52

我正在Visual Studio中使用TableAdapter查询配置向导编写以下SQL查询。

SELECT  COUNT(*) AS census
FROM Inventory INNER JOIN Taxonomy ON Inventory.GlobalID = Taxonomy.GlobalID
WHERE (Inventory.Institution = @institution) AND (Inventory.Year = @year) AND 
  (Inventory.Nending > 0)

我试图将以下条件添加到WHERE子句中:

(Taxonomy.Class = ISNULL(@class, Taxonomy.Class)) 

以便
1) 只返回与@class输入参数匹配的行或
2) 返回所有行,而不管其TaxonomyGlobal.Class值如何。

当我将此语句添加到查询中时,调用该查询的C#代码会抛出System.ArgumentNullException错误,并声明@class值不能为null。

如有任何关于如何将此标准添加到WHERE子句的帮助,我们将不胜感激。

C#代码:

namespace CollectionMetrics
{
  class DatabaseQueries
  {
      QueryDataSetTableAdapters.InventoryTableAdapter queryAdapter = 
            new QueryDataSetTableAdapters.InventoryTableAdapter();
      public void CensusQuery(string institution, short year, string xclass)
      {
            int census = 0;
            string localClass = xclass;
            if (xclass == "All Classes") localClass = null;
            census = (int)queryAdapter.CensusBySpecies(localClass, institution, year);
            censusOutput.Add(census);
      }
  }
}

使用ISNULL的SQL查询

SQL:

(@class IS NULL OR Taxonomy.Class = @class)

由于您使用的是TableAdapter,因此需要编辑字段以允许空值:

https://msdn.microsoft.com/en-us/library/ms233762.aspx

设置AllowDbNull属性

为了使查询能够在数据集设计器中接受空值,选择需要接受null参数的TableAdapter查询价值观在"属性"窗口中选择"参数",然后单击省略号(…)按钮打开参数集合编辑器。选择允许null值并设置AllowDbNull属性的参数真实。

如果您正在使用SqlParameters:

C#

 var param = new SqlParameter("@class", (object) classVariable ?? DBNull.Value);

classVariable替换为您在代码中使用的变量的名称,以设置@class SqlParameter的值。由于变量与DBNull的类型不同,因此需要强制转换为object

我曾经尝试过做你想做的事情,认为这是一种很好的方法,可以忽略没有从前端传递的参数(因此为NULL)。

但后来我了解到,像这样在WHERE子句中使用ISNULL()会阻止索引的使用,使您的查询比使用时慢得多

WHERE (Taxonomy.Class = @Class OR @Class IS NULL)

我承认,这是不合直觉的;您尝试的方法看起来更干净,因此速度更快,但对于SQL性能,最重要的是使用可用索引,因此事实证明A OR B方法实际上比您想要使用的ISNULL()方法更快。

至于为什么会出现错误,这肯定是向导强制执行的。如果您纯粹在SQL中尝试查询(使用SSMS),它会允许的。除非您的查询实际上在存储过程中,并且@Class是必需的参数。