Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql rn NULL。我只对简单的查询执行过此操作,因此我不知道它将如何影响较长/复杂的查询。_Sql_Sql Server_Sql Server 2005_Sql Server 2008 - Fatal编程技术网

Sql rn NULL。我只对简单的查询执行过此操作,因此我不知道它将如何影响较长/复杂的查询。

Sql rn NULL。我只对简单的查询执行过此操作,因此我不知道它将如何影响较长/复杂的查询。,sql,sql-server,sql-server-2005,sql-server-2008,Sql,Sql Server,Sql Server 2005,Sql Server 2008,如果您希望返回零,如果发生零除法,您可以使用: SELECT COALESCE(dividend / NULLIF(divisor,0), 0) FROM sometable 对于每一个为零的除数,您将在结果集中得到一个零。当错误传播回调用程序时,您可以适当地处理它(或者如果您想要忽略它)。在C#中,SQL中发生的任何错误都会抛出一个异常,我可以捕获该异常,然后在代码中进行处理,就像其他错误一样 我同意贝斯卡的观点,你不想隐瞒错误。您可能没有处理核反应堆,但通常隐藏错误是糟糕的编程实践。这是大

如果您希望返回零,如果发生零除法,您可以使用:

SELECT COALESCE(dividend / NULLIF(divisor,0), 0) FROM sometable

对于每一个为零的除数,您将在结果集中得到一个零。

当错误传播回调用程序时,您可以适当地处理它(或者如果您想要忽略它)。在C#中,SQL中发生的任何错误都会抛出一个异常,我可以捕获该异常,然后在代码中进行处理,就像其他错误一样

我同意贝斯卡的观点,你不想隐瞒错误。您可能没有处理核反应堆,但通常隐藏错误是糟糕的编程实践。这是大多数现代编程语言实现结构化异常处理以将实际返回值与错误/状态代码解耦的原因之一。这在你做数学的时候尤其如此。最大的问题是,您无法区分返回的正确计算的0和错误导致的0。相反,返回的任何值都是计算值,如果出现任何错误,将引发异常。当然,这取决于您访问数据库的方式和使用的语言,但您应该始终能够得到一条可以处理的错误消息

try
{
    Database.ComputePercentage();
}
catch (SqlException e)
{
    // now you can handle the exception or at least log that the exception was thrown if you choose not to handle it
    // Exception Details: System.Data.SqlClient.SqlException: Divide by zero error encountered.
}
这似乎是解决被零除的问题的最佳解决方案,我的数据中确实存在这种情况。 假设您想计算各种学校俱乐部的男女比例,但您发现以下查询失败,并在尝试计算没有女性的指环王俱乐部的比例时发出被零除的错误:

SELECT club_id, males, females, males/females AS ratio
  FROM school_clubs;
您可以使用函数
NULLIF
避免被零除
null如果
比较两个表达式,如果它们相等,则返回null,否则返回第一个表达式

将查询重写为:

SELECT club_id, males, females, males/NULLIF(females, 0) AS ratio
  FROM school_clubs;
任何数字除以
NULL
得到
NULL
,并且不会生成错误。

对于更新SQL:

update Table1 set Col1 = Col2 / ISNULL(NULLIF(Col3,0),1)

如果存在被零除的情况,您至少可以阻止查询因错误而中断,并返回
NULL

SELECT a / NULLIF(b, 0) FROM t 
然而,我决不会像在另一个得到了很多赞成票的答案中所显示的那样,用
合并
将其转换为零。这在数学意义上是完全错误的,甚至是危险的,因为您的应用程序可能会返回错误和误导性的结果

使用
NULLIF(exp,0)
但是这样-
NULLIF(ISNULL(exp,0),0)

CREATE FUNCTION dbo.Divide(@Numerator Real, @Denominator Real)
RETURNS Real AS
/*
Purpose:      Handle Division by Zero errors
Description:  User Defined Scalar Function
Parameter(s): @Numerator and @Denominator

Test it:

SELECT 'Numerator = 0' Division, dbo.fn_CORP_Divide(0,16) Results
UNION ALL
SELECT 'Denominator = 0', dbo.fn_CORP_Divide(16,0)
UNION ALL
SELECT 'Numerator is NULL', dbo.fn_CORP_Divide(NULL,16)
UNION ALL
SELECT 'Denominator is NULL', dbo.fn_CORP_Divide(16,NULL)
UNION ALL
SELECT 'Numerator & Denominator is NULL', dbo.fn_CORP_Divide(NULL,NULL)
UNION ALL
SELECT 'Numerator & Denominator = 0', dbo.fn_CORP_Divide(0,0)
UNION ALL
SELECT '16 / 4', dbo.fn_CORP_Divide(16,4)
UNION ALL
SELECT '16 / 3', dbo.fn_CORP_Divide(16,3)

*/
BEGIN
    RETURN
        CASE WHEN @Denominator = 0 THEN
            NULL
        ELSE
            @Numerator / @Denominator
        END
END
GO
NULLIF(exp,0)
在exp为
null时中断
但是
NULLIF(ISNULL(exp,0),0)
不会中断

将“除以零”替换为零是有争议的,但这也不是唯一的选择。在某些情况下,用1替换是(合理的)合适的。我经常发现自己在使用

 ISNULL(Numerator/NULLIF(Divisor,0),1)
当我查看分数/计数的变化时,如果没有数据,我希望默认为1。比如说

NewScore = OldScore *  ISNULL(NewSampleScore/NULLIF(OldSampleScore,0),1) 

通常情况下,我在其他地方计算过这个比率(不仅仅是因为它可以为低分母抛出一些非常大的调整因子。在这种情况下,我通常会控制OldSampleScore大于一个阈值;这会排除零。但有时“hack”是合适的。

有时,0可能不合适,但有时1也不合适。有时从0跳转将100000000描述为1%或100%的变化也可能具有误导性。100000000%可能适用于这种情况。这取决于您打算根据百分比或比率得出什么样的结论

例如,一个非常小的销售项目从售出的2-4件变为售出的,一个非常大的销售项目从售出的1000000件变为2000000件,这对分析师或管理层来说可能意味着非常不同的事情,但两者都会以100%或1%的变化来实现

隔离空值可能比搜索一堆混合了合法数据的0%或100%行更容易。通常,分母中的0表示错误或缺少值,并且您可能不希望仅仅为了使数据集看起来整洁而填充任意值

CASE
     WHEN [Denominator] = 0
     THEN NULL --or any value or sub case
     ELSE [Numerator]/[Denominator]
END as DivisionProblem

我就是这样修复的:

IIF(ValueA != 0, Total / ValueA, 0)
它可以包装在更新中:

SET Pct = IIF(ValueA != 0, Total / ValueA, 0)
或在选择中:

SELECT IIF(ValueA != 0, Total / ValueA, 0) AS Pct FROM Tablename;

想法?

嗨,Ron,很好的解决方案,只是数据类型有限(小数点后4位)我们的@除数也可以是负数。那么如何强制使用它呢?TIA Henrik Staun PoulsenI很快就完成了它,以处理当时的特定问题场景。单开发者应用程序,因此强制执行除了我的内存之外没有那么难。:-)尽管有print语句,但它不是一个存储过程,而是一个标量UDF。在MS-SQL中,如果它是查询的一部分,这将杀死你。我同意Mark Sowul的断言,即标量函数将导致痛苦。这在T-SQL中是一个可怕的建议,不要这样做!标量函数是性能的毁灭者!内嵌表值函数是唯一的好方法SQL Server中的d个用户函数(可能除了执行良好的CLR函数外)。您可以用表达式
@numerator/NULLIF(@divisor,0)替换整个函数
。它也是这样做的,而且速度更快。我不同意。你的业务规则永远不应该做非法的数学运算。如果你最终做了这样的事情,你的数据模型很可能是错误的。每当你遇到除以0时,你应该考虑数据是否应该为NULL而不是0。我不敢相信我被别人否决了谁会问我是否“做过真正的编程?”因为我说的是做对,而不是懒惰。对不起,我不是有意冒犯你。但这个问题在很多常见的LOB应用程序中都是完全有效的,用“除以0是不合法的”来回答它不增加IMHO的价值。@JackDouglas是的。这是一种您希望业务规则以特殊方式处理特殊情况的情况……但它不应该是基础
NewScore = OldScore *  ISNULL(NewSampleScore/NULLIF(OldSampleScore,0),1) 
CASE
     WHEN [Denominator] = 0
     THEN NULL --or any value or sub case
     ELSE [Numerator]/[Denominator]
END as DivisionProblem
IIF(ValueA != 0, Total / ValueA, 0)
SET Pct = IIF(ValueA != 0, Total / ValueA, 0)
SELECT IIF(ValueA != 0, Total / ValueA, 0) AS Pct FROM Tablename;