금백조의 개발 블로그

[MSSQL]CHAR, NCHAR 문자열 자료형 사용시 주의사항 본문

Database/SQL Server(MSSQL)

[MSSQL]CHAR, NCHAR 문자열 자료형 사용시 주의사항

금백조 2021. 2. 6. 13:43
반응형

서론

 

회사에서 개발하는 도중 DB에서 두 테이블을 조회한 결과로 소스 상에서 컬럼 간 문자열 데이터를 비교하여 일치하면 특정 문자열로 변환하여 보여주는 로직이 있었습니다. 그러나 육안으로 확인했을 때는 동일한 문자열임에도 특정 데이터로 변환되지 않는 문제를 겪었습니다. 원인을 파악해보니 남은 문자열 자리 수에 공백이 기본적으로 들어가는 NCHAR와 공백 없이 가변적으로 문자열 자리 수를 갖는 NVARCHAR 자료형 간의 비교로 인해 발생하는 문제였습니다. 이 과정 속에서 알게 된 CHAR, NCHAR 사용 시에 주의사항에 대해 적어볼까 합니다.

 


 

본론

 

CHAR, NCHAR 자료형을 가진 컬럼에 데이터를 INSERT 하게 되면 남은 문자열 길이만큼 오른쪽에 공백이 채워지게 됩니다. VARCHAR, NVARCHAR 자료형은 공백 없이 자료형이 INSERT 됩니다. 따라서 VAR가 있으면 가변 길이 문자열이 되며 VAR가 없으면 고정길이 문자열이 됩니다.

아래의 간단한 예제를 실행해보면 문자열에 실제 공백이 들어가는지 안 들어가는지를 확인할 수 있습니다.

 

[자료 INSERT시 CHAR, NCHAR, VARCHAR, NVARCHAR 공백 확인 예제]

 

CREATE TABLE #TEMP_TABLE(
	 CHAR_COLUMN CHAR(10)
	,NCHAR_COLUMN NCHAR(10)
	,VARCHAR_COLUMN VARCHAR(10)
	,NVARCHAR_COLUMN NVARCHAR(10)
)

INSERT INTO #TEMP_TABLE
SELECT
 'CODE1' AS NCHAR_FLG
,'CODE1' AS NVARCHAR_FLG
,'CODE1' AS CHAR_FLG
,'CODE1' AS VARCHAR_FLG

SELECT 
	   CHAR_COLUMN    +'CODE2' AS CHAR_COLUMN--CODE1과 CODE2 사이에 공백 존재
	  ,NCHAR_COLUMN   +'CODE2' AS NCHAR_COLUMN--CODE1과 CODE2 사이에 공백 존재
	  ,NVARCHAR_COLUMN+'CODE2' AS NVARCHAR_COLUMN--CODE1과 CODE2 사이에 공백 없음
	  ,VARCHAR_COLUMN +'CODE2' AS VARCHAR_COLUMN--CODE1과 CODE2 사이에 공백 없음
FROM #TEMP_TABLE

 

[실행 결과]

 

 

위와 같이 문자열을 더한 결과를 보면 CHAR, NCHAR 자료형의 경우 5자리수인 'CODE1'이 입력되고 남은 5 자릿수에 공백이 추가되는 걸 알 수 있습니다. 반면 VARCHAR, NVARCHAR 자료형의 경우 자릿수를 가변적으로 갖기에 공백이 추가되지 않습니다.

따라서 위의 조회된 결과를 소스상에서 string 형식으로 변환하여 비교하면 아래와 같은 비교가 이루어질 것입니다. 소스는 C#을 예로 들겠습니다. 두 문자열이 일치할 때 특정 문자열을 "REPLACE" 문자로 변환하는 예제입니다.

 

[소스상에서의 문자열 비교]

 

string strNchar = "CODE1     CODE2";//DB에서 조회된 NCHAR_COLUMN 컬럼-공백이 들어감
string strNvarchar = "CODE1CODE2";//DB에서 조회된 NVARCHAR_COLUMN 컬럼

if(strNchar.equals(strNvarchar)){//strNchar에 공백이 포함되어 false
	strNchar = "REPLACE";//실행되지 않음
}

 

저는 위와 같이 공백으로 인해 문자열이 일치하지 않는 것을 해결하기 위하여 CHAR, NCHAR 자료형을 갖는 컬럼을 조회할 때 REPLACE 함수를 통해 공백을 제거하여 해결했습니다.

 

[REPLACE 함수를 통한 공백 제거]

 

CREATE TABLE #TEMP_TABLE(
	 CHAR_COLUMN CHAR(10)
	,NCHAR_COLUMN NCHAR(10)
	,VARCHAR_COLUMN VARCHAR(10)
	,NVARCHAR_COLUMN NVARCHAR(10)
)

INSERT INTO #TEMP_TABLE
SELECT
 'CODE1' AS NCHAR_FLG
,'CODE1' AS NVARCHAR_FLG
,'CODE1' AS CHAR_FLG
,'CODE1' AS VARCHAR_FLG

SELECT 
	   REPLACE(CHAR_COLUMN,' ','')    +'CODE2' AS CHAR_COLUMN--REPLACE를 통한 공백 제거
	  ,REPLACE(NCHAR_COLUMN,' ','')   +'CODE2' AS NCHAR_COLUMN--REPLACE를 통한 공백 제거
	  ,NVARCHAR_COLUMN+'CODE2' AS NVARCHAR_COLUMN
	  ,VARCHAR_COLUMN +'CODE2' AS VARCHAR_COLUMN
FROM #TEMP_TABLE

 

[실행 결과]

 

 

 

[소스상에서의 문자열 비교]

 

string strNchar = "CODE1CODE2";//DB에서 조회된 NCHAR_COLUMN 컬럼-REPLACE로 인해 공백이 제거됨
string strNvarchar = "CODE1CODE2";//DB에서 조회된 NVARCHAR_COLUMN 컬럼

if(strNchar.equals(strNvarchar)){//true
	strNchar = "REPLACE";//정상 실행
}

 

따라서 공백 제거를 통해 문자열 비교가 정상적으로 이루어지는 것을 확인할 수 있습니다.

 


 

결론

 

CHAR, NCHAR 자료형을 조회하면 공백으로 인해 문제가 생길 수도 있다는 것을 알게 되었습니다. 다음에도 위와 같은 유사한 문제가 발생했을 땐 테이블의 컬럼 자료형을 먼저 파악하는 습관을 길러야겠습니다.

 

Reference

 

[봉자의 지식창고] - [MSSQL] char, nchar, varchar, nvarchar

https://likeban.tistory.com/entry/MSSQL-char-nchar-varchar-nvarchar

반응형