2017-12-13 17 views
-5

유효성 검사 저장 프로 시저에 쿼리가 있습니다. 그것은 이런 식입니다 :SQL Server 쿼리의 이상한 동작

SELECT * 
FROM Table1 
WHERE batchID IN (SELECT id FROM #tempIds) 
    AND CAST(field1 AS DATE) > CAST(field2 AS DATE) 

모두 field1field2이 필드 1/2 반환 1.

#tempIds 테이블은 하나의 열 ID을 가지고 있으며, 하나의 행을 포함에 IdDate을하고, 즉, 유효 기간이있다. 나는 위의 쿼리를 실행하면

, 나는이 오류가 :

Unable to convert varchar to date

하지만 그 대신 나는 그것이 작동 같은 임시 테이블에서 하드 코드 된 ID를 넣어 경우 임시 테이블에서 일괄 ID를 선택.

어떤 아이디어가 문제 일 수 있습니까?

+5

"varchar를 날짜로 변환 할 수 없습니다."는 'field1' 또는'field2'는 날짜로 변환 할 수없는 varchar 값을 가짐을 나타냅니다. 오류 텍스트는 아주 자명합니다. –

+0

#tempIds가 하나의 행만 가질 경우 id 값을 로컬 변수에 할당하고 where 절에 "="가 아닌 IN을 해당 로컬 변수로 사용합니다. – prabhu379

+0

? 당신이 묘사하는 것은 말이되지 않습니다. – Paparazzi

답변

2

varchar을 사용하여 date (또는 datetime) 값을 저장하는 것이 문제입니다.
열에 올바른 데이터 형식을 선택하면 많은 문제를 방지 할 수 있습니다. 자세한 내용은 Aaron Bertrand의 Bad habits to kick : choosing the wrong data type을 참조하십시오.

이제 대화에서 설명을 설명합니다. SQL Server는 where 절의 조건이 평가되는 순서를 보장하지 않습니다. 즉, 두 열의 모든 "날짜"문자열이 특정 batchID의 날짜 값으로 변환 될 수있는 경우 "varchar을 (를) 날짜로 변환 할 수 없음"오류를 발생 시키려면 열 중 하나에서 잘못된 값 하나만 필요합니다. 미래의 독자를 위해 - 그래서 -이가 자신의 제안 :

SELECT * 
FROM Table1 
WHERE batchID IN (SELECT id FROM #tempIds) 
AND ISDATE(field1) = 1 
AND ISDATE(field2) = 1 
AND CAST(field1 AS DATE) > CAST(field2 AS DATE) 

이었다 이것은 또한 당신이 어디 쿼리 래리 B는 그의 대답에 제안 된 방법을 쓸 경우에도 (지금은 삭제 된 것을 의미한다

isdate(field1)=1 조건 이후에 마지막 조건 (cast(field1 as date) > cast(field2 as date))이 으로 평가된다는 보장이 없습니다.

올바르게 수행 할 작업은 문제를 해결하는 것입니다. - 열의 데이터 형식을 올바른 데이터 형식으로 변경하십시오. (데이터베이스의 구조 통제 할 수없는 경우 예를 들어,) 그 가정

할 수 없습니다 - 당신은 몇 가지 작업을 수행 할 수 있습니다

  1. 모든 장소를 찾아 어디 값 field1field2에있는 날짜는 날짜로 변환하여 수정할 수 없습니다. check 제약 조건을 추가하여 이러한 열의 값을 날짜로 변환 할 수 있는지 확인하십시오 (가능한 경우).2 개 부분으로

  2. 별도의 쿼리 :

;With cte as 
(
    SELECT * 
    FROM Table1 
    WHERE batchID IN (SELECT id FROM #tempIds) 
    AND ISDATE(field1) = 1 
    AND ISDATE(field2) = 1 
) 
SELECT * 
FROM cte 
WHERE CAST(field1 AS DATE) > CAST(field2 AS DATE) 

이 당신 만 ISDATE 기능은 이미 1을 반환 값을 캐스팅하기 때문에 오류를 제거하지만, 당신이 원하는 어떤 행을 반환하지 않을 수 있습니다 이 행에 field1 또는 field2 중 하나가 잘못된 경우 값을 반환합니다.

+0

감사합니다. Zohar, 사실 Table1은 데이터웨어 하우스 테이블이며 파일의 데이터가이 테이블에로드되고 해당 데이터를 실제 비즈니스 테이블로 이동하기 전에 데이터의 유효성을 검사해야합니다 ... 그 오류가 발생한 곳입니다. ...이 솔루션은 작동합니다 ... 답변을 주셔서 감사합니다 ... – Yogeshwar

+0

@ ZoharPeled 내 솔루션이 올바르지 않아 삭제했습니다. 하지만 제 질문은 그 질문이 나쁠 때 도움이되고 싶다는 것이 었습니다. 그가 질문을 했었고 where 절에 isdate를 포함 시켰 더라면 나는 당신이 그것을 쉽게 발견했을 것입니다. 이제 그는 그가 절대로 깨닫지 못했던 사실에 대한 질문이 어떤 부분을 설명 했으므로 where 절의 평가 순서에 대해 설명합니다. 어떻게 그렇게 오래 동안 많은 SQL 변형을 사용했는지 결코 깨닫지 못했습니다. 네가 두 대있어! –

+1

@LarryB 첫째, 나는 다른 사람을 도울 수있어서 기쁘다. 둘째, 나는 당신이 당신을 삭제 한 이후에 제안 된 SQL을 보여주기 위해 나의 대답을 편집했다. –