我在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);
}
}
}
答案 0 :(得分:2)
SQL:
(@class IS NULL OR Taxonomy.Class = @class)
由于您使用的是TableAdapter
,因此您需要编辑字段以允许空值:
https://msdn.microsoft.com/en-us/library/ms233762.aspx
设置AllowDbNull属性
启用查询以接受空值在数据集设计器中, 选择需要接受null参数的TableAdapter查询 值。在Properties窗口中选择Parameters,然后单击 省略号(...)按钮打开参数集合编辑器。选择 允许空值的参数并设置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()
是必需参数。