получить аргумент nvarchar из БД в DLL

Чтобы подготовиться к миграции с SQL Anywhere 16 на SQL Anywhere 17, я должен убедиться, что все функции, предоставляемые DLL, будут работать с UTF-8.

До сих пор StoredProcedures БД принимали varchar (x) в качестве параметров и передавали их в DLL, которая работала нормально.

Procedure code:

create procedure dba.stp_DLLGetData
(
in as_Input1         varchar(30),
in as_Input2         nvarchar(12)
)
external name '[email protected]'
language C_ESQL32
go

Вход 1 обрабатывается как ранее с ANSI.
Вход 2 — это та часть, которую я не могу заставить работать.

DLL code:

void GetData(an_extfn_api* extapi, void* arg_handle){
int         iRc = 0;
wstring     wstrInput1(L"");
wstring     wstrInput2(L"");
string      argTemp;
wstring     wstrTemp;
LPWSTR      pUnicodeString;

//get wstrInput1
if (iRc == 0){
iRc = getArgumentVarchar(extapi, arg_handle, 1, &argTemp);
if (iRc != 0){
iRc = -1;
}
else{
pUnicodeString = ConvertToUNICODE(argTemp.c_str());
wstrInput1 = wstring(pUnicodeString);
free(pUnicodeString);
argTemp.clear();
}
}

//get wstrInput2
if (iRc == 0){
iRc = getArgumentNvarchar(extapi, arg_handle, 2, &wstrInput2);
if (iRc != 0){
iRc = -1;
}
}
}

int getArgumentVarchar(an_extfn_api* extapi, void* arg_handle, int iArgNum, string* argString){
short       params;
unsigned    offset;
an_extfn_value argument;

params = extapi->get_value(arg_handle, iArgNum, &argument);
if (params == 0 || argument.data == NULL){
return 1;
}
if (argument.type != DT_VARCHAR){
return -1;
}
argString->clear();
offset = 0;
for( ; params != 0; ){
if (argument.data == NULL) break;
argString->append((char *) argument.data, argument.piece_len);
offset += argument.piece_len;
if (argument.piece_len == 0) break;
params = extapi->get_piece(arg_handle, iArgNum, &argument, offset);
}
return 0;
}

int getArgumentNvarchar(an_extfn_api* extapi, void* arg_handle, int iArgNum, wstring* argString){
short       params;
unsigned    offset;
an_extfn_value argument;

wchar_t*     bla;

params = extapi->get_value(arg_handle, iArgNum, &argument);
if (params == 0 || argument.data == NULL){
return 1;
}
if (argument.type != DT_NVARCHAR){       //error 1
return -1;
}
argString->clear();
offset = 0;
for( ; params != 0; ){
if (argument.data == NULL) break;
argString->append((wchar_t*) argument.data, argument.piece_len); //error2
offset += argument.piece_len;
if (argument.piece_len == 0) break;
params = extapi->get_piece(arg_handle, iArgNum, &argument, offset);
}
return 0;
}

Сначала я подумал: «Эй, легко, поменяйте местами типы данных и все», но оказалось, что все сложнее.
Согласно документации БД, nvarchar в SQL должен ссылаться на DT_NVARCHAR в C.

-SQL-         |  -data type-    |    -sqldef.h C type-
VARCHAR       | DT_VARCHAR      | Character data, with specified length
LONG VARCHAR  | DT_LONGVARCHAR  | Character data, with specified length
NVARCHAR      | DT_NVARCHAR     | UTF-8 character data, with specified length
LONG NVARCHAR | DT_LONGNVARCHAR | UTF-8 character data, with specified length

Во время отладки (входные параметры бота содержат строку ‘evo01’), когда я проверяю тип данных аргумента (error1), типом аргумента аргумента тип-аргумента является DT_LONGVARCHAR вместо DT_NVARCHAR.
«Нет проблем», — подумал я, возможно, оценка как-то не так.
Если я пропущу проверку типа данных и продолжу, я получаю тарабарщину только после применения wchar_t * к аргументу.
Если я применяю char * к тому же nvarchar arguments.data, то получаю вместо ‘evo01’.

Может кто-то указать, что я делаю не так?

РЕДАКТИРОВАТЬ: обновить
Поскольку БД продолжает передавать недопустимый контент, и у меня заканчиваются идеи, я решил использовать обходной путь и передать аргументы через длинный двоичный файл.
Не самое выгодное решение, но работающее без нареканий.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]