SQLCLR 聚合:没有关于消除 NULL 值的消息

SQLCLR Aggregate: no message about NULL values being eliminated

当我做

SELECT SUM(some_field) FROM some_table

结果是一个 record/field,里面有一个数字。此外,如果 some_field 在 table 某处有一个 NULL 值,将会有一条消息沿着 Warning: Null value is eliminated by an aggregate or other SET operation. 行发送给客户端。只有当它们都是NULL(或table为空)时才会return NULL.

我目前正在编写我自己的 SqlUserDefinedAggregate,虽然一切按预期工作,但它 NOT 在传递的值之一结果为为空。该功能的结果仍然正确,但没有警告。首先,我假设我可能必须在 Terminate() 方法中手动 pipe,但是,唉,SQLCLR 然后抛出一个 InvalidOperationExceptionData acces is not allowed in this context.

有什么提示吗?

如果您的聚合正在丢弃 NULL,那么 IsInvariantToNulls 属性 绝对应该设置为 true 否则您有时可能会得到意想不到的结果,如SqlUserDefinedAggregateAttribute.IsInvariantToNulls 的 MSDN 页面:

Used by the query processor, this property is true if the aggregate is invariant to nulls. That is, the aggregate of S, {NULL} is the same as aggregate of S. For example, aggregate functions such as MIN and MAX satisfy this property, while COUNT(*) does not.

Incorrectly setting this property can result in incorrect query results. This property is not an optimizer hint; it affects the plan selected and the results returned by the query.

而 UDA 是一个函数,因此没有 SqlContext.Pipe 可以使用。即使有,Terminate 方法也不是处理此问题的合适位置,因为它对每个组都执行。然而,您在使用 SUM 时看到的警告是一个 ANSI 警告,并且针对查询显示一次,而不是针对每个组显示一次。

因此,如果 SQL 服务器未显示警告,那么您可能无能为力。我假设 SQL 服务器没有使用 IsInvariantToNulls 属性 作为知道它是否应该显示消息的手段,因为不能保证它被准确设置。

我个人认为这是一个好处,因为在我看来,"Null value is eliminated by an aggregate" 警告完全没有帮助,但如果你想摆脱它,你需要使用 ISNULL() 来注入一个不会影响结果的值(例如 0SUM 的情况下),或者关闭所有 ANSI 警告,在这种情况下,您可以禁用一些有时有用的警告。