使用ISNULL的SQL查询

时间:2016-07-27 18:33:01

标签: c# sql-server

我在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);
      }
  }
}

2 个答案:

答案 0 :(得分:2)

SQL:

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

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

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

设置AllowDbNull属性

  

启用查询以接受空值在数据集设计器中,   选择需要接受null参数的TableAdapter查询   值。在Properties窗口中选择Para​​meters,然后单击   省略号(...)按钮打开参数集合编辑器。选择   允许空值的参数并设置AllowDbNull属性   为真。

如果您使用SqlParameters

C#

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

classVariable替换为您在代码中使用的变量名称,以设置@class SqlParameter的值。转换为object是必需的,因为该变量与DBNull的类型不同。

答案 1 :(得分:0)

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

但后来我了解到在这样的ISNULL()子句中使用WHERE可以防止使用索引,使得查询比使用时更慢:

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

我不承认,不直观;你尝试的方式看起来会更干净,因此更快,但对于SQL性能,最重要的是使用可用的索引,因此事实证明A OR B方法实际上比{{1}更快你想要使用的方法。

至于为什么你会收到错误,它必须是向导强制执行的操作。如果您纯粹在SQL(使用SSMS)中尝试过查询,那么它将允许它。除非您的查询实际上在存储过程中,ISNULL()是必需参数。