Данные в Юникоде и кодовые страницы сервера
Важно! |
---|
В будущей версии Microsoft SQL Server эта возможность будет удалена. Не используйте ее при работе над новыми приложениями и как можно быстрее измените приложения, в которых она в настоящее время используется. Пользуйтесь вместо этого интеграцией со средой CLR. |
API-интерфейс расширенных хранимых процедур распознает данные в кодировке Юникод, однако он не распознает метаданные в Юникоде. Директива #define Юникода не влияет на API-интерфейс расширенных хранимых процедур.
Все метаданные, возвращаемые или поставляемые API-интерфейсу расширенных хранимых процедур из приложения, должны быть в многобайтовой кодовой странице сервера. По умолчанию приложениями сервера API-интерфейса расширенных хранимых процедур используется кодовая страница ANSI компьютера, на котором запущено приложение. Эту кодовую страницу можно получить с помощью вызова srv_pfield со значением параметра поля SRV_SPROC_CODEPAGE.
Если приложение с API-интерфейсом расширенных хранимых процедур поддерживает Юникод, необходимо преобразовать имена столбцов метаданных, сообщения об ошибках и т.д. в многобайтовые данные, прежде чем передавать эти данные в API-интерфейс расширенных хранимых процедур.
Примеры
В следующей расширенной хранимой процедуре приведен пример указанного преобразования Юникода. Обратите внимание на следующее.
Данные столбца передаются в srv_describe как данные Юникода, поскольку тип столбца – SRVNVARCHAR.
Метаданные имени столбца передаются в srv_describe как многобайтовые данные.
Расширенная хранимая процедура вызывает srv_pfield со значением параметра поля SRV_SPROC_CODEPAGE для получения многобайтовой кодовой страницы Microsoft SQL Server.
Сообщения об ошибках передаются в srv_sendmsg как многобайтовые данные.
__declspec(dllexport) RETCODE proc1 (SRV_PROC *srvproc){ #define MAX_COL_NAME_LEN 25 #define MAX_COL_DATA_LEN 50 #define MAX_ERR_MSG_LEN 250 #define MAX_SERVER_ERROR 20000 #define XP_ERROR_NUMBER MAX_SERVER_ERROR+1 int retval; UINT serverCodePage; CHAR *szServerCodePage; WCHAR unicodeColumnName[MAX_COL_NAME_LEN]; CHAR multibyteColumnName[MAX_COL_NAME_LEN]; WCHAR unicodeColumnData[MAX_COL_DATA_LEN]; WCHAR unicodeErrorMessage[MAX_ERR_MSG_LEN]; CHAR multibyteErrorMessage[MAX_ERR_MSG_LEN]; lstrcpyW (unicodeColumnName, L"column1"); lstrcpyW (unicodeColumnData, L"column1 data"); lstrcpyW (unicodeErrorMessage, L"No Error!"); // Obtain server code page. // szServerCodePage = srv_pfield (srvproc, SRV_SPROC_CODEPAGE, NULL); if (NULL != szServerCodePage) serverCodePage = atol(szServerCodePage); else { // Problem situation exists. srv_senddone(srvproc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0, 0); return 1; } // Convert column name for Unicode to multibyte using the // server code page. // retval = WideCharToMultiByte( serverCodePage, // code page 0, // default unicodeColumnName, // wide-character string -1, // string is null terminated multibyteColumnName, // address of buffer for new // string sizeof (multibyteColumnName), // size of buffer NULL, NULL); if (0 == retval) { lstrcpyW (unicodeErrorMessage, L"Conversion to multibyte failed."); goto Error; } retval = srv_describe (srvproc, 1, multibyteColumnName, SRV_NULLTERM, SRVNVARCHAR, MAX_COL_DATA_LEN*sizeof(WCHAR), // destination SRVNVARCHAR, lstrlenW(unicodeColumnData)*sizeof(WCHAR), unicodeColumnData); //source if (FAIL == retval) { lstrcpyW (unicodeErrorMessage, L"srv_describe failed."); goto Error; } retval = srv_sendrow(srvproc); if (FAIL == retval) { lstrcpyW (unicodeErrorMessage, L"srv_sendrow failed."); goto Error; } retval = srv_senddone (srvproc, SRV_DONE_MORE|SRV_DONE_COUNT, 0, 1); if (FAIL == retval) { lstrcpyW (unicodeErrorMessage, L"srv_senddone failed."); goto Error; } return 0;Error: // convert error message from Unicode to multibyte. retval = WideCharToMultiByte( serverCodePage, // code page 0, // default unicodeErrorMessage, // wide-character string -1, // string is null terminated multibyteErrorMessage, // address of buffer for new // string sizeof (multibyteErrorMessage), // size of buffer NULL, NULL);srv_sendmsg(srvproc, SRV_MSG_ERROR, XP_ERROR_NUMBER, SRV_INFO, 1, NULL, 0, __LINE__, multibyteErrorMessage, SRV_NULLTERM); srv_senddone(srvproc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0, 0); return 1;}