SQL에서 "0으로 나누기"오류를 피하는 방법은 무엇입니까?


363

이 오류 메시지가 있습니다 :

메시지 8134, 수준 16, 상태 1, 줄 1 오류 0으로 나눕니다.

이 오류 메시지가 다시 표시되지 않도록 SQL 코드를 작성하는 가장 좋은 방법은 무엇입니까?

다음 중 하나를 수행 할 수 있습니다.

  • 제수가 제로가 아닌 where 절을 추가하십시오.

또는

  • case statement를 추가하여 0에 대한 특별한 처리가 가능합니다.

NULLIF절 을 사용하는 가장 좋은 방법 입니까?

더 좋은 방법이 있습니까, 아니면 어떻게 시행 할 수 있습니까?


7
아마도 일부 데이터 유효성 검사가 순서대로되어있을 것입니다.
Anthony

답변:


644

"0으로 나누기"오류를 피하기 위해 다음과 같이 프로그래밍했습니다.

Select Case when divisor=0 then null
Else dividend / divisor
End ,,,

그러나 여기에 훨씬 좋은 방법이 있습니다.

Select dividend / NULLIF(divisor, 0) ...

이제 유일한 문제는 "/"키를 사용하면 NullIf 비트를 기억하는 것입니다.


13
제수가 NULL 인 경우 "배당 / nullif (divisor, 0) ..."을 선택하는 훨씬 좋은 방법입니다.
Anderson

8
@ 앤더슨 그것은 사실이 아닙니다. 실수로 IsNull대신 사용하지 않았 NullIf습니까? 직접 해보십시오! SELECT Value,1/NullIf(Value,0)FROM(VALUES(0),(5.0),(NULL))x(Value);"breaks"가 아니라면 NULL을 반환한다는 의미입니까? 당신은 당신이 원하는대로로 변환 할 수 있습니다 IsNull또는 Coalesce.
ErikE

1
@ErikE, 그것은 사실입니다 ... 실행을 시도 ... select 1 / nullif (null, 0) ... 당신은 얻을 "첫 번째 인수의 유형이 있기 때문에 NULLIF의 첫 번째 인수의 유형은 NULL 상수가 될 수 없습니다 알려질 것입니다. " "coalesce (FieldName, 0)"을 사용하여이를 처리하십시오. 예 : select 1 / nullif (coalesce (null, 0), 0)
John Joseph

1
@JohnJoseph 나는 당신이 나에게 동의하거나 나에게 논쟁하고 있는지 말할 수 없다.
ErikE

1
@JohnJoseph 발생한 오류를 자세히 살펴보십시오. 예, SELECT 1 / NULLIF(NULL, 0)실패하지만 NULLIF()첫 번째 인수의 데이터 유형을 알아야 하기 때문 입니다. 이 변경된 예는 정상적으로 작동합니다 SELECT 1 / NULLIF(CAST(NULL AS INT), 0). 실제로 NULLIF()NULL상수 가 아닌 테이블 열을 제공하려고합니다 . 테이블 열에는 알려진 데이터 유형이 있으므로 다음과 같이 작동합니다 SELECT 1 / NULLIF(SomeNullableColumn, 0) FROM SomeTable.
MarredCheese

180

0을 반환하려는 경우 0 수정이 발생할 경우 다음을 사용할 수 있습니다.

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

제수가 0 인 모든 제수에 대해 결과 집합에서 0을 얻습니다.


9
일부 벤치 마크에서는 COALESCE가 ISNULL보다 약간 느립니다. 그러나 COALESCE는 표준에 있으므로 이식성이 뛰어납니다.
Paul Chernoch

37
다른 사람이 이것이 왜 작동하는지 즉시 알 수 없으면 d가 0이면 NULLIF (d, 0)이 NULL을 반환합니다. SQL에서 NULL로 나누면 NULL이 반환됩니다. Coalesce는 결과 NULL을 0으로 대체합니다.
GuiSim

16
@SQLGeorge 귀하의 주장에 동의하지만, 수학적으로 올바른 것보다 통계적으로 올바른 것을 더 중요하게 생각하는 경우가 있습니다. 통계 함수를 사용할 때 제수가 0 인 경우 0 또는 1이 허용되는 결과 일 수 있습니다.
Athafoud

10
왜 이것이 나쁜지 설명해 줄 수 있습니까? 백분율을 알아 내려고 시도하고 제수가 0이면 결과가 0 %가되기를 원합니다.
Todd Sharp

10
@George와 @ James / Wilson은 묻는 질문을 근본적으로 오해한다고 생각합니다. 수학적으로 볼 때 기술적으로 사실이 아니더라도 "0"을 반환하는 것이 적절한 비즈니스 응용 프로그램이 있습니다.
Sean Branchaw

66

이것은 데이터에서 발생하는 0으로 나누기를 해결하려고 할 때 내 상황에 가장 적합한 것으로 보였습니다.

다양한 학교 클럽의 남녀 비율을 계산하려고하는데 다음 쿼리가 실패하고 반지가없는 클럽의 비율을 계산하려고 할 때 0으로 나누기 오류가 발생한다고 가정합니다. :

SELECT club_id, males, females, males/females AS ratio
  FROM school_clubs;

이 기능 NULLIF을 사용하면 0으로 나누지 않아도됩니다. NULLIF두 표현식을 비교하고 같으면 null을 반환하고 그렇지 않으면 첫 표현식을 반환합니다.

다음과 같이 쿼리를 다시 작성하십시오.

SELECT club_id, males, females, males/NULLIF(females, 0) AS ratio
  FROM school_clubs;

주어진 수로 나눈 값 NULLNULL오류가 발생하지 않습니다.


6
그렇습니다 . 그것은 많은 찬사를받은 다른 답변 보다 훨씬 더 나은 방법 입니다. 솔루션에 최소한 NULL이 있으며 이는 올바른 결과를 제공 할 수 없음을 나타냅니다. 그러나 결과를 NULL에서 0으로 변환하면 잘못되고 잘못된 결과를 얻을 수 있습니다.
SQL 경찰

8
그건 그렇고, 남성 / 여성 비율을 계산하려면 다음과 같이 합계와 비교하는 것이 좋습니다 select males/(males+females), females/(males+females). 이것은 31 %의 남성, 69 %의 여성과 같은 클럽에서 남성과 여성의 비율 분포를 제공합니다.
SQL 경찰

44

쿼리 시작시이 작업을 수행 할 수도 있습니다.

SET ARITHABORT OFF 
SET ANSI_WARNINGS OFF

따라서 이와 같은 100/0것이 있으면 NULL을 반환합니다. 간단한 쿼리에 대해서만이 작업을 수행 했으므로 더 길고 복잡한 쿼리에 어떤 영향을 줄지 모르겠습니다.


1
나를 위해 작동합니다. 필자의 경우 WHERE 절에서 나누기 연산을 사용해야합니다. WHERE를 주석 처리 할 때 결과에 ​​0 값이 없기 때문에 제로 디바이더가 없다고 확신합니다. 그러나 어떻게 든 쿼리 최적화 프로그램은 필터링하는 동안 0으로 나눕니다. SET ARITHABORT OFF SET 및 ANSI_WARNINGS OFF는 2 일 동안 WHERE 절에서 0으로 나누고 싸운 후에 작동합니다. 고마워!
huhu78

2
이것은 "더러워"너무 더럽지 만 사랑합니다! 집계를 수행하고 CASE 문을 사용하는 쿼리에서 필요했지만 옵션을 전혀 사용하지 않았기 때문에 결과를 완전히 변경 한 GROUP BY에 해당 열을 추가해야했습니다. 초기 쿼리를 하위 선택으로 만들고 외부 쿼리에서 GROUP BY를 수행하면 나누기가 관련되어 있기 때문에 결과가 변경됩니다.
Andrew Steitz

1
그래, 난 여전히이 "솔루션"을 좋아하지만 많은 사람들이 아마 "깨끗한"방법이 있어야한다고 느꼈습니다. 경고를 다시 활성화하는 것을 잊어 버린 경우 어떻게합니까? 아니면 누군가 내 코드를 복제하고 (그렇지 않은가?) 경고에 대해 생각하지 않았습니까? 어쨌든 NULLIF ()에 대한 다른 답변을 보았습니다. NULLIF ()에 대해 알고 있었지만 NULL로 나누는 것이 NULL을 반환한다는 것을 알지 못했습니다 (오류라고 생각했습니다). 그래서 ... 나는 다음과 함께 갔다 : ISNULL ((SUM (foo) / NULLIF (SUM (bar), 0)), 0) AS Avg
Andrew Steitz

2
나는이 해결책을 몰랐다. 마음에 들지 모르겠지만 언젠가 알고 있으면 도움이 될 것입니다. 대단히 감사합니다.
Henrik Staun Poulsen

1
가장 쉬운 솔루션이지만 성능이 저하 될 수 있습니다. 에서 docs.microsoft.com/en-us/sql/t-sql/statements/... : "OFF로 ARITHABORT를 설정하면 성능에 부정적인 문제로 이어지는 쿼리 최적화에 영향을 미칠 수 있습니다."
mono blaine

36

오류로 인해 쿼리가 중단되는 것을 최소한 중지하고 NULL0으로 나눈 값을 반환 할 수 있습니다.

SELECT a / NULLIF(b, 0) FROM t 

그러나 많은 찬사를 얻은 다른 답변에 표시된 것처럼 절대로 이것을 0으로 변환하지 않습니다 coalesce. 이것은 수학적 의미에서 완전히 잘못되었으며 응용 프로그램에서 잘못되고 잘못된 결과를 반환 할 수 있으므로 위험합니다.


32

편집 : 최근에 많은 downvotes가 생겼습니다 ... 그래서이 답변이 가장 최근의 편집을 받기 전에 작성되었다는 메모를 추가한다고 생각했습니다 .null을 반환하는 것이 옵션으로 강조 표시되었습니다. 매우 수용 가능한 것 같습니다. 내 대답 중 일부는 Edwardo와 같은 문제에 대한 답변에서 0을 반환하는 것을 옹호하는 것처럼 보였습니다. 이것은 내가 반대하는 경우입니다.

답변 : 여기에 근본적인 문제가 있다고 생각합니다 .0으로 나누는 것은 합법적이지 않습니다. 뭔가 근본적으로 잘못되었음을 나타냅니다. 0으로 나누면 수학적으로 이해가되지 않는 것을 시도하고 있으므로 얻을 수있는 숫자 답변이 유효하지 않습니다. (이 경우 널을 사용하면 나중에 수학적 계산에 사용될 값이 아니므로 합리적입니다).

따라서 Edwardo는 "사용자가 0을 입력하면 어떻게됩니까?"라는 의견을 묻습니다. 사용자가 금액에 0을 넣고 그 때 0을 반환하려면 비즈니스 규칙 수준에서 코드를 입력하여 해당 값을 포착하고 0을 반환해야합니다 .0으로 나누는 특별한 경우는 없습니다 = 0.

그것은 미묘한 차이이지만, 다음에 누군가가 함수를 호출하고 올바른 일을 할 것으로 기대하기 때문에 수학적으로 정확하지 않지만 펑키 한 일을하지만 특정 에지 케이스를 처리하기 때문에 중요합니다. 나중에 누군가를 물릴 수있는 좋은 기회입니다. 당신은 실제로 0으로 나누지 않습니다 ... 당신은 단지 나쁜 질문에 대한 잘못된 대답을 반환합니다.

내가 무언가를 코딩하고 있다고 상상해보십시오. 나는 방사선 측정 스케일링 값으로 읽어야하지만 이상한 가장자리 케이스에서는 예상하지 못했지만 0을 읽습니다. 그런 다음 내 값을 함수에 버립니다 ... 당신은 0을 반환합니다! 만세, 방사선 없음! 그것이 실제로 있다는 것을 제외하고는 내가 나쁜 가치를 전달했다는 것입니다 ...하지만 나는 모른다. 뭔가 잘못되었다는 표시이기 때문에 나누기가 오류를 던지기를 원합니다.


15
동의하지 않습니다. 비즈니스 규칙은 절대로 불법적 인 수학을해서는 안됩니다. 이와 같은 작업을 수행하면 데이터 모델이 잘못되었을 가능성이 큽니다. 당신은 0으로 나누기가 발생할 때마다 당신은 숙고해야 할 데이터는 NULL 대신에 0이었던해야하는 경우
레무스 Rusanu

32
"실제 프로그래밍을 해 본 적이 있습니까?" 내가 게으 르기보다는 옳게하라는 말을하기 때문입니다. 한숨
Beska

11
죄송합니다. 기분을 상하게 할 의도는 없었습니다. 그러나이 질문은 많은 일반적인 LOB 응용 프로그램에서 완벽하게 유효하며 "0으로 나누는 것은 합법적이지 않습니다"라는 대답은 IMHO의 가치를 추가하지 않습니다.
Eduardo Molteni

2
@JackDouglas 맞습니다. 비즈니스 규칙에서 특별한 경우를 특수한 방식으로 처리하려는 경우입니다. 그러나 공백을 반환하는 기본 수학이 아니어야합니다. 비즈니스 규칙이어야합니다. 허용 된 답변은 null을 반환하므로 처리하는 것이 좋습니다. 예외를 던지는 것도 괜찮습니다. SQL로 가기 전에 그것을 발견하고 처리하는 것이 틀림없이 이상적입니다. 수학적으로 잘못된 값을 반환하는 다른 것들이 호출 할 수있는 기능을 제공하는 것은 갈 길이 아닙니다 . 그 특별한 경우는 다른 호출자에게는 적용되지 않을 수 있기 때문입니다.
Beska

4
@JackDouglas 그렇습니다. 좋은 의견입니다. 원래이 질문은 "이 오류를 숨기려면 어떻게해야합니까?"로 표현되었습니다. 그 이후로 진화했습니다. null을 반환하면 결국 대답이 하나의 합리적인 응답처럼 보입니다. (나는 0 또는 다른 숫자를 반환하지 않도록 강력히 주장했다.)
Beska

28
SELECT Dividend / ISNULL(NULLIF(Divisor,0), 1) AS Result from table

nullif ()를 사용하여 0을 포착 한 다음 isnull ()을 사용하여 결과로 생성 된 널을 0으로 나누면 0으로 나누기 오류를 피할 수 있습니다.


3
길이가 길어 답변을 삭제하는 것이 좋습니다. 매우 단순 해 보이지만 제안하는 내용에 대해 작은 설명을 추가하는 것이 좋습니다.
Trinimon

10

"0으로 나누기"를 0으로 바꾸는 것은 논란의 여지가 있지만 유일한 옵션은 아닙니다. 어떤 경우에는 1로 대체하는 것이 (합리적으로) 적절합니다. 나는 종종 내 자신을 발견

 ISNULL(Numerator/NULLIF(Divisor,0),1)

점수 / 횟수의 변화를보고 데이터가없는 경우 기본값을 1로 설정하려고합니다. 예를 들어

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

종종이 비율을 다른 곳에서 계산했습니다. (낮은 분모에 대해 매우 큰 조정 요소를 던질 수 있기 때문입니다.이 경우 일반적으로 OldSampleScore에 대한 제어가 임계 값보다 큽니다. 그러나 때때로 '핵'이 적합합니다.


1
@N 메이슨; 예, 때로는 1이 옵션입니다. 그러나 백 슬래시를 입력 할 때 ISNULL 부분을 어떻게 기억하십니까?
Henrik Staun Poulsen

1
죄송합니다 Henrik-질문을 이해하지 못했습니다.
N 메이슨

6

저장 프로 시저 에서 처리하기 위해 함수를 잠시 작성했습니다 .

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

2
안녕하세요 Ron, Nice 솔루션입니다. 제한된 데이터 유형 (소수점 4 자리)을 가지며 @divisors는 음수 일 수 있습니다. 그리고 어떻게 사용하도록 강요합니까? TIA Henrik Staun Poulsen
Henrik Staun Poulsen

1
당시 특정 문제 시나리오를 처리하는 데 매우 빠릅니다. 단일 개발자 앱이므로 메모리를 제외하고는 그렇게 어렵지 않습니다. :-)
Ron Savage

5
print 문에도 불구하고, 저장된 proc이 아니며 스칼라 UDF입니다. 쿼리의 일부인 경우 MS-SQL에서 종료됩니다.
Mark Sowul

4
나는 스칼라 함수가 통증을 유발할 것이라는 마크 소울의 주장에 동의했다. 이것은 T-SQL에서 끔찍한 제안입니다.하지 마십시오! 스칼라 함수는 성능 파괴자입니다! 인라인 테이블 값 함수는 SQL Server에서 유일하게 우수한 사용자 함수입니다 (성능이 우수한 CLR 함수 제외).
Davos

4
  1. Divisor0이 아닌 강제 로 CHECK 제약 조건 추가
  2. 사용자가이 필드에 0 값을 입력 할 수 없도록 양식에 유효성 검증기를 추가하십시오.

1
CHECK 제약 조건이 점점 더 좋아지기 시작합니다.
Henrik Staun Poulsen

4

업데이트 SQL의 경우 :

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

3
안녕 Vijay, 그래, 작동합니다,하지만 난 당신이 NULL로 나누어 결국 ISNULL 부분에 대해 조심할 것입니다. 제수가 0이므로 결과를 알 수 없음을 사용자에게 알립니다.
Henrik Staun Poulsen

2
복잡한 하위 쿼리에 저장되었습니다. 감사합니다.
QMaster

3

마법 글로벌 설정 '0 예외로 나누기 해제'는 없습니다. x / 0의 수학적 의미가 NULL 의미와 다르기 때문에 연산을 처리해야하므로 NULL을 리턴 할 수 없습니다. 나는 당신이 명백한 것을 돌보고 있다고 가정하고 쿼리에는 0 제수가있는 레코드를 제거하고 나누기를 평가하지 않아야하는 조건이 있다고 가정합니다. 대부분의 개발자들이 SQL은 절차 적 언어처럼 행동 할 것으로 예상하고 논리 연산자 단락을 제공하는보다 일반적인 '잡았다'이지만 않습니다 NOT . 이 기사를 읽는 것이 좋습니다. http://www.sqlmag.com/Articles/ArticleID/9148/pg/2/2.html


4
"매직 글로벌 설정"이 있습니다; SET ARITHABORT OFF.
David Manheim

3

다음은 0으로 나눌 수있는 상황입니다. 비즈니스 규칙은 재고 회전을 계산하기 위해 일정 기간 동안 판매 된 상품 비용을 가져 와서 연간 화하는 것입니다. 연간 수치를 얻은 후에는 해당 기간의 평균 재고로 나눕니다.

3 개월 동안 발생하는 재고 회전 수를 계산하려고합니다. 3 개월 동안 1,000 달러의 재화가 판매 된 것으로 계산했습니다. 연간 판매율은 $ 4,000 ($ 1,000 / 3) * 12입니다. 초기 재고는 0입니다. 최종 재고는 0입니다. 평균 재고는 이제 0입니다. 매년 $ 4000의 판매량을 가지고 있으며 재고는 없습니다. 이것은 무한한 회전 수를 산출합니다. 이는 고객이 내 모든 재고를 변환하고 구매 함을 의미합니다.

이것은 재고 회전을 계산하는 방법에 대한 비즈니스 규칙입니다.


3
그렇습니다, 당신은 무한한 회전 수 를 갖습니다 . 따라서이 경우 0으로 나누면 '#INF'와 같은 것을 표시해야합니다.
SQL 경찰

1
"시작 인벤토리는 0입니다. 끝 인벤토리는 0입니다. 평균 인벤토리는 이제 0입니다." 귀하의 계산은 추정치입니다. 때때로 재고가 긍정적이거나 아무것도 선적 / 판매 할 수 없습니다. 결과적으로 + ∞에 만족하지 않으면 평균 재고를 더 잘 추정하십시오.
Tom Blodget

2
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

UDF를 사용하면 쿼리가 단일 스레드 모드로 실행되므로 솔루션이 마음에 들지 않습니다. 테스트 설정이 마음에 듭니다. 모든 UDF에 적용하고 싶습니다.
Henrik Staun Poulsen

나에게이 솔루션은 완벽하고 우아합니다
Payedimaunt

@Payedimaunt; 예, UDF는 매우 우아한 코드로 이어집니다. 그러나 성능이 좋지 않습니다. 이것은 "수면제에 커서"입니다. :-) 평범한 "/"대신 dbo.Divide를 쓰는 것도 기억하기 어렵습니다.
Henrik Staun Poulsen


1

때로는 0이 적절하지 않을 수 있지만 때로는 1도 적합하지 않습니다. 때로는 1 또는 100 %의 변화로 설명되는 0에서 100,000,000으로의 점프도 오해의 소지가 있습니다. 이 시나리오에서는 100,000,000 %가 적합 할 수 있습니다. 백분율 또는 비율을 기반으로 어떤 결론을 내릴 것인지에 따라 다릅니다.

예를 들어, 판매량이 2-4 개에서 매우 작은 판매 품목과 1,000,000에서 2,000,000 개로 변경된 매우 큰 판매 품목은 분석 가나 경영진에게 매우 다른 의미를 지닐 수 있지만 둘 다 100 % 또는 1 개로 나옵니다. 변화.

합법적 인 데이터와 혼합 된 0 % 또는 100 % 행을 검색하는 것보다 NULL 값을 분리하는 것이 더 쉬울 수 있습니다. 종종 분모의 0은 오류 또는 누락 된 값을 나타낼 수 있으며, 데이터 세트를 깔끔하게 보이도록 임의의 값을 채우고 싶지 않을 수도 있습니다.

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

1
문제는 분할을 원할 때마다 무언가를하는 것을 기억하는 것입니다. CASE 또는 NULLIF 추가를 기억하지 못하면 월요일 아침 x 주 동안 지원 사례를받습니다. 나는 그것을 싫어한다.
Henrik Staun Poulsen

1

이것이 내가 고친 방법입니다.

IIF (ValueA! = 0, 총계 / ValueA, 0)

업데이트로 감쌀 수 있습니다.

SET Pct = IIF (ValueA! = 0, 총계 / ValueA, 0)

또는 선택 :

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

생각?


나와 다른 사람들은 "알 수 없음"을 0으로 바꾸는 것이 위험한 해결책이라는 것을 알게되었습니다. 나는 NULL을 선호합니다. 그러나 어려운 부분은 모든 부서에 iif 또는 nullif를 추가하는 것입니다!
Henrik Staun Poulsen

0

호출 프로그램으로 다시 전파 될 때 적절하게 오류를 처리 할 수 ​​있습니다 (또는 원하는 경우 무시하십시오). C #에서 SQL에서 발생하는 모든 오류는 다른 오류와 마찬가지로 코드를 잡고 처리 할 수있는 예외를 throw합니다.

나는 당신이 오류를 숨기고 싶지 않다는 점에서 Beska에 동의합니다. 원자로를 다루지 않을 수도 있지만 일반적으로 오류를 숨기는 것은 나쁜 프로그래밍 관행입니다. 이것이 대부분의 최신 프로그래밍 언어가 실제 반환 값을 오류 / 상태 코드와 분리하기 위해 구조적 예외 처리를 구현하는 이유 중 하나입니다. 수학을 할 때 특히 그렇습니다. 가장 큰 문제는 올바르게 계산 된 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.
}

1
우리 모두 0으로 오류를 숨기는 것이 해결책이 아니라는 데 동의합니다. 내가 제안하는 것은 모든 "/"뒤에 "NULLIF"가 오도록 코드를 작성하는 것입니다. 이런 식으로 내 보고서 / 핵 원자로는 혼자 남겨지지 않지만 그 성가신 오류 메시지 8134 대신 "NULL"이 표시됩니다. 제수가 0 일 때 다른 프로세스가 필요한 경우 Beska와 동의합니다. 코드를 작성해야합니다. "/"를 쓸 때마다 수행하기가 어렵습니다. "/ NULLIF"가 항상 불가능한 것은 아닙니다.
Henrik Staun Poulsen

0

사용 NULLIF(exp,0)하지만 이런 식으로-NULLIF(ISNULL(exp,0),0)

NULLIF(exp,0)exp가 null있지만 NULLIF(ISNULL(exp,0),0)중단되지 않으면 중단


1
0이 o가 아닌 0이면 NULLIF (exp, 0)를 얻을 수 없습니다. 시험; DECLARE @i INT SELECT 1 / NULLIF (@i, 0)를 사용하여 중단 될 수 있는지 확인하십시오.
Henrik Staun Poulsen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.