2009-07-16 2 views
1

SQL language lawyer이 도움이 될 수있는 SQL 표준에 대한 질문이 있습니다.SQL 표준의 오류 값 처리

특정 표현식이 작동하지 않습니다. 예 : 62/0. SQL 표준은 비슷한 방식으로 표현이 잘못 될 수있는 몇 가지 방법을 지정합니다. 특수한 예외 흐름 제어 또는 bottom 가짜 값을 사용하여 이러한 표현을 많은 언어가 처리합니다.

두 개의 열이있는 t 테이블이 각각 intxy입니다. 나는 그것이 관련이 없다고 의심하지만, 확실성을 위해서 의 기본 키가 (x,y)이라고 가정 해 봅시다. 이 표는 (만) 다음과 같은 값을 포함합니다 : 어떤 동작은 0으로 나누기 (들)을 포함 할 수있다이 테이블에서 작동 SELECT 표현의 SQL 표준에 의해 요구되는

x y 
7 2 
3 0 
4 1 
26 5 
31 0 
9 3 

? 또는 어떤 행동도 필요하지 않으면 어떤 행동이 허용됩니까?

예를 들어 다음 select 문에는 어떤 동작이 필요합니까?

쉬운 하나

SELECT x, y, x/y AS quot 
FROM t 

더 단단한 하나

SELECT x, y, x/y AS quot 
FROM t 
WHERE y != 0 

이보다 더 열심히 일 :

SELECT x, y, x/y AS quot 
FROM t 
WHERE x % 2 = 0 

겠습니까에 실현하는 데 실패 구현 (예를 들어, 하나 확장 내에서 제한을 이동할 수있는이 쿼리의보다 복잡한 버전)을 생산에 허용 할 수 있습니다. 이 쿼리에 대한 응답으로 0으로 나누기 오류가 발생했습니다. 제한을 수행하기 전에 30으로 나눠서 시도한 결과 3 % 2 = 1이 발생했기 때문입니다. 예를 들어, 확장이 작은 테이블 위에 있었지만 큰 테이블과 조인되고 큰 테이블의 데이터를 기반으로 제한 될 경우 결과는 모든 행을 제한하는 결과를 가져옵니다. 0으로 나누어야한다.

t가 수백만 개의 행을 가지고 있고이 마지막 쿼리가 테이블 스캔에 의해 수행 된 경우 구현은 x의 짝수 값 하나가 발생할 때 끝 근처에서 0으로 나누기를 발견하기 전에 처음 몇 백만 개의 결과를 반환하도록 허용됩니까? y의 값은 0입니까? 버퍼링해야합니까?

SELECT x, y 
FROM t 
WHERE ((x/y) >= 2) AND ((x % 2) = 0) 

테이블이 큰 경우,이 짧은 :

는 제한에 부울 논리 값 사를 의미에 따라하는 부울 단락을 파괴하거나 요구할 수이 하나 더 나쁜 경우가 숙고하다 - 회로 문제는 정말 미칠 수 있습니다. 테이블에 백만 개의 행이 있고 그 중 하나에 0 개의 제수가 있다고 상상해보십시오. 어떤 표준이 말을하는 것은의 의미입니다 :

SELECT CASE 
     WHEN EXISTS 
      (
       SELECT x, y, x/y AS quot 
       FROM t 
      ) 
     THEN 1 
     ELSE 0 
     END AS what_is_my_value 

그것은 오류가 발생 공허함이나 결과의 비 공허함에 따라 다르지만 때문에 아마 오류해야이 값 것 같아 그 의미를 것 채택 여기서 테이블 스캔을 단락시키는 최적화 프로그램을 금지하는 것 같습니다.이 존재 쿼리는 바닥이 아닌 행이 하나 존재하는지 또는 바닥 행이 존재하지 않는지를 입증해야합니까? 내가 사양의 관련 부분을 (를) 찾을 수 없습니다 때문에

나는 여기에 지침을 감사하겠습니다.

+1

내게 맞는 질문이 아닙니다. 구현은 일반적으로 표준에 의해 지정되지 않습니다 ... –

+0

무슨 뜻입니까?이 경우 표준에서 요구하는 동작은 무엇입니까? 존재하는 경우 값이 결과 집합에 나타날 것이라는 확신이있을 때까지 이러한 "예외적 인"상황에 대한 통지를 지연시키기위한 준수 구현이 필요합니까? 반대로, 적합성있는 구현체는 호출자가 만날 때마다 호출자에게 "예외적 인"상황을 알려주고, 그 값이 존재한다면 나중에 결합 또는 제한에 의해 결과 집합에서 제외되지 않았 음을 입증하지 못합니다 ? –

답변

1

함께 작업 한 모든 SQL 구현은 0으로 나누기를 즉치 NaN 또는 #INF으로 처리합니다. 부서는 구현 자체가 아니라 프런트 엔드에서 처리해야합니다. 쿼리는 밑바닥이되어서는 안되지만이 경우 결과 집합은 NaN을 반환해야합니다. 따라서 결과 집합과 동시에 반환되고 특별한 경고 또는 메시지가 사용자에게 표시되지 않습니다. 제대로이 처리 할 수있는 속도로

가, 다음 쿼리 사용 : 마지막 질문에 대답하기

select 
    x, y, 
    case y 
     when 0 then null 
     else x/y 
    end as quot 
from 
    t 

을,이 사항 :

SELECT x, y, x/y AS quot 
FROM t 

이 반환됩니다 :

x y quot 
7 2 3.5 
3 0 NaN 
4 1  4 
26 5 5.2 
31 0 NaN 
9 3  3 

그래서, 당신의 existst, 등록의 모든 행을 찾을 것입니다 그들의 몫이 무의미했습니다.

또한, 나는 다시 질문을 통해 읽고 있었다 나는 where 절을 논의하지 않았 실현 (수치를 위해!). 열이 계산되기 전에 where 절 또는 predicate항상이 적용되어야한다.

이 쿼리에 대한 생각 :

select x, y, x/y as quot from t where x%2 = 0 

우리가 레코드 (3,0)를 가지고 있다면, 그것은 where 조건을 적용하고 확인 3 % 2 = 0 경우. 그렇게하지 않으면 열 계산에 해당 레코드가 포함되지 않고 그대로있는 것입니다.