2012-05-11 2 views
3

현재 Delphi 2007 코드베이스를 모두 Delphi XE2로 업데이트하는 중입니다. 가장 큰 고려 사항은 모든 기본 유형 (char/string)을 ANSI 유형 (ansichar/ansistring)으로 다시 정의하여 처리 한 ANSI 대 유니 코드 변환입니다. 이것은 데이터베이스 작업을 시작할 때까지 많은 프로그램에서 작동했습니다.유니 코드 변환, 데이터베이스 문제 (Delphi 2007에서 XE2)

파일에서 읽은 정보를 저장하는 프로그램을 SQL Server 2008 데이터베이스로 변환 할 때 문제가 발생했습니다.

SELECT id FROM table WHERE name = 'something' 

name 필드가 varchar입니다 : 같은 데이터가 실패 찾을 문자열을 사용 갑자기 간단한 쿼리. 문자열 이름 앞에 N이라는 접두사를 붙이면 쿼리를 성공적으로 완료 할 수있었습니다. 나는 varchar만이 ANSI 문자를 저장할 수 있다고 생각했지만 유니 코드를 저장하는 것으로 보입니까?

몇 가지 추가 정보 : 델파이의 이름 필드는 string[13]이지만 나는 [13]을 삭제하려고 시도했습니다. 데이터베이스 데이터 정렬은 SQL_Latin1_General_CP1_CI_AS입니다. 우리는 ADO를 사용하여 데이터베이스와 인터페이스합니다. 연결 정보는 ODBC 관리자에 저장됩니다.

참고 : Panagiotis의 지시에 따라 실제 문제가 해결되었습니다. 지도 파일에서 읽은 이름은 array[1..24] of AnsiChar입니다. 이 값은 암시 적으로 null 문자를 포함하는 string[13]으로 변환되었습니다. 따라서 5 문자로 된 이름은 실제로 데이터베이스에 5 문자 + 8 문자로 저장되었습니다.

답변

2

varchar 필드에는 유니 코드 문자가 저장되지 않습니다. 필드의 데이터 정렬에 지정된 코드 페이지에 ASCII 값을 저장합니다. 다른 코드 페이지의 유니 코드 또는 데이터를 저장하려고하면 SQL Server는 try to convert characters을 올바른 코드 페이지로 바꿉니다. 이 기능을 비활성화 할 수 있지만 가장 좋은 방법은 응용 프로그램에서 nvarchar 필드와 UnicodeString을 사용하여 전체적인 혼란을 피하는 것입니다.

모든 문자 유형을 응용 프로그램의 UNICODE 유형이 아닌 ANSI로 변경한다고 언급했습니다. UNICODE를 사용하려면 UnicodeString과 같은 UNICODE 유형을 사용해야합니다. 그렇지 않으면 값이 서버로 전송 될 때 ANSI로 변환됩니다. 이 변환은 서버로 전송되는 AnsiString을 만들 때 코드에 의해 수행됩니다.

지금까지 SELECT 문은 ASCII 값을 필드에 저장합니다. 당신은 당신이 유니 코드 값으로 저장하려는 경우에도이 데이터가 유니 코드 형태로 서버에 도달 할 것이라는 점을 보장하지 않습니다

SELECT id FROM table WHERE name = N'something' 

을 eg.g, N과 값을 앞에 추가해야합니다. AnsiString에 문을 저장하면 서버에 보내기 전에 전체 문이 ANSI로 변환됩니다. 앱이 잘못된 변환을하면 서버에서 데이터가 엉망이됩니다.

솔루션은 매우 간단합니다. 매개 변수가있는 명령문을 사용하여 유니 코드 값을 유니 코드 매개 변수로 전달하고이를 NVarchar 필드에 저장하면됩니다. 훨씬 빠르며 모든 변환 오류를 방지하고 SQL 주입 공격을 방지합니다.

+0

불행히도, 나는 내가 바꿀 수있는 것에 매우 제한되어 있습니다. 유니 코드를 완전히 포용하고 싶지만 시스템의 절반은 Visual C++ 4.2로 작성되었습니다. 우리는 또한 진정한 유니 코드 변환이 재정적으로 가능하지 않은 매우 복잡한 시스템과 몇 가지 코드를 공유합니다.나는 당신이 말한 것을 취하고 문제가 발생하고있는 곳을 더 잘 진단하려고 노력할 것입니다. –