회사에서 프로시저 디버깅 중
같은 파라미터 값을 PRINT와 SELECT로 출력했는데 결과가 달랐던 경험이 있었다.
놀랍게도
PRINT로 출력한 값은 정상 SELECT로 출력한 값은 일부가 잘려 다른 값으로 나왔다 결론부터 말하면 원인은 MSSQL의 암묵적 타입 변환(Data Type Precedence) 이다.
다음과 같이 하나의 파라미터 값을 출력했다.
DECLARE @score DECIMAL(10,4) = 123.4567
PRINT @score
SELECT @score AS score
처음에는 둘 다 같아 보여서 문제 없어 보였다.
그런데 실제 문제는 문자열과 함께 출력하려고 할 때 발생했다.
DECLARE @score DECIMAL(10,4) = 123.4567
PRINT 'score = ' + CAST(@score AS VARCHAR(20))
SELECT 'score = ' + @score AS score
PRINT
→ score = 123.4567 ✅ (정상)
SELECT
→ score = 123 ❌ (소수점 손실)
같은 파라미터인데 결과가 다르다.
MSSQL은 서로 다른 타입을 연산할 때
우선순위가 높은 타입으로 변환한다.
즉, 아래 코드에서:
SELECT 'score = ' + @score
MSSQL은 내부적으로 이렇게 처리한다.
SELECT CAST('score = ' AS DECIMAL) + @score
결과적으로
PRINT는 내부적으로
NVARCHAR(4000)으로 암묵적 변환을 수행한다.
즉, 다음과 같은 처리에 가깝다.
PRINT CAST(@score AS NVARCHAR)
그래서:
👉 그래서 PRINT는 맞고 SELECT는 틀려 보이는 현상이 발생한 것
SELECT 'value = ' + @score
SELECT 'value = ' + CAST(@score AS VARCHAR(20))
또는
SELECT CONCAT('value = ', @score)
👉 CONCAT은 내부적으로 문자열 변환을 안전하게 처리함
CONCAT() 사용PRINT가 맞고
SELECT가 틀릴 수 있다
→ 문제는 SELECT가 아니라 타입 처리
실무에서는
명시적 CAST를 습관화하는 게 가장 안전한 방법이다.