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


Кодовая страница данных Юникода и серверных кодов

Область применения: SQL Server

Внимание

Эта функция будет удалена в будущей версии 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 получения многобайтовой кодовой страницы 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;
    }