Поделиться через


Данные в Юникоде и кодовые страницы сервера

Важное примечаниеВажно!

В будущей версии 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;}