我有这个错误信息:
Msg 8134,级别16,状态1,第1行,除以零错误。
写SQL代码的最好方法是什么,这样我就再也不会看到这个错误消息了?
我可以做以下任何一件事:
添加where子句,使除数永远不为零
Or
我可以添加一个case语句,这样就可以对0进行特殊处理。
使用NULLIF子句是最好的方法吗?
有没有更好的办法,或者如何实施?
我有这个错误信息:
Msg 8134,级别16,状态1,第1行,除以零错误。
写SQL代码的最好方法是什么,这样我就再也不会看到这个错误消息了?
我可以做以下任何一件事:
添加where子句,使除数永远不为零
Or
我可以添加一个case语句,这样就可以对0进行特殊处理。
使用NULLIF子句是最好的方法吗?
有没有更好的办法,或者如何实施?
当前回答
我是这样解决的:
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;
想法吗?
其他回答
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
我写了一个函数来处理我的存储过程:
print 'Creating safeDivide Stored Proc ...'
go
if exists (select * from dbo.sysobjects where name = 'safeDivide') drop function safeDivide;
go
create function dbo.safeDivide( @Numerator decimal(38,19), @divisor decimal(39,19))
returns decimal(38,19)
begin
-- **************************************************************************
-- Procedure: safeDivide()
-- Author: Ron Savage, Central, ex: 1282
-- Date: 06/22/2004
--
-- Description:
-- This function divides the first argument by the second argument after
-- checking for NULL or 0 divisors to avoid "divide by zero" errors.
-- Change History:
--
-- Date Init. Description
-- 05/14/2009 RS Updated to handle really freaking big numbers, just in
-- case. :-)
-- 05/14/2009 RS Updated to handle negative divisors.
-- **************************************************************************
declare @p_product decimal(38,19);
select @p_product = null;
if ( @divisor is not null and @divisor <> 0 and @Numerator is not null )
select @p_product = @Numerator / @divisor;
return(@p_product)
end
go
使用NULLIF(exp,0),但以这种方式- NULLIF(ISNULL(exp,0),0)
如果exp为空,NULLIF(exp,0)将中断,但NULLIF(ISNULL(exp,0),0)将不会中断
如果你想返回零,如果发生零分割,你可以使用:
SELECT COALESCE(dividend / NULLIF(divisor,0), 0) FROM sometable
对于每一个为0的除数,结果集中都会得到一个0。
你也可以在查询的开头这样做:
SET ARITHABORT OFF
SET ANSI_WARNINGS OFF
如果你有100/0,它会返回NULL。我只做了简单的查询,所以我不知道它会如何影响更长的/复杂的查询。