У меня есть приложение C++, построенное на RHEL 5, которое подключается к MS SQL 2008 через freeTDS и unixODBC, расположенные на машине Windows.Невозможно вставить символы Юникода через freetds unixODBC в MS SQL 2008
Это запрос, который приложение отправляет в базу данных.
INSERT INTO mytable (SAMPLE) VALUES(N'乕乭乺丕')
[email protected]@Iz
фактически вводится в базу данных, когда вышеупомянутый запрос вызывается.
Ниже приведены конфигурации, которые я использую -
== freetds.conf ==
[myserver.mydomain.com]
client charset = UTF-16
debug flags = 0xffff
dump file = /tmp/dump.log
dump file append = yes
host = 127.0.01
port = 1433
tds version = 7.3
== odbcinst.ini ==
[FreeTDS Driver]
Description = FreeTDS
Driver = /usr/lib64/libtdsodbc.so.0
== odbc.ini ==
[mydsn]
Description = MS SQL connection to 'mydb' database
Driver = FreeTDS Driver
Servername = myserver.mydomain.com
Port = 1433
TDS_Version = 7.3
Database = mydb
UserName = sa
Password = mypassword
Trace = Yes
TraceFile = /tmp/odbc.log
ForceTrace = Yes
Я могу напрямую вставить данные в базу данных через
INSERT INTO mytable (SAMPLE) VALUES(N'乕乭乺丕')
но не через FreeTDS и UnixODBC
Вы можете найти код, который я использую ниже:
#include <iostream>
#ifdef WIN32
#include <windows.h>
#endif
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include "unicode/ustdio.h"
using namespace std;
int main (int argc, char* argv[])
{
SQLHSTMT hSQLStatement = 0;
SQLHENV hSQLEnvironment = 0;
SQLHDBC hSQLODBC = 0;
SQLRETURN sqlRet = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hSQLEnvironment);
if(SQL_SUCCEEDED(sqlRet))
{
sqlRet = SQLSetEnvAttr(hSQLEnvironment,
SQL_ATTR_ODBC_VERSION,
(void*)SQL_OV_ODBC3,
0);
if(SQL_SUCCEEDED(sqlRet))
{
sqlRet = SQLAllocHandle(SQL_HANDLE_DBC,
hSQLEnvironment,
&hSQLODBC);
}
else
{
cout << "Error in SQLAllocHandle for SQL_HANDLE_DBC" << endl;
}
}
else
{
cout << "Error in SQLAllocHandle for SQL_HANDLE_ENV" << endl;
}
UnicodeString DSNName = "mydsn";
UnicodeString UserName = "sa";
UnicodeString Password = "mypassword";
UnicodeString Value = "";
UChar32 character = 20053;
Value.append(character);
character = 20077;
Value.append(character);
character = 131140;
Value.append(character);
character = 131145;
Value.append(character);
character = 20090;
Value.append(character);
character = 19989;
Value.append(character);
UnicodeString SQLStatement = "INSERT INTO mytable (sample) VALUES(N";
SQLStatement.append("'");
SQLStatement.append(Value);
SQLStatement.append("'");
SQLStatement.append(")");
if(0 != hSQLODBC)
{
SQLRETURN sqlRet = SQLConnectW(hSQLODBC,
(SQLWCHAR*)DSNName.getTerminatedBuffer(),
SQL_NTS,
(SQLWCHAR*)UserName.getTerminatedBuffer(),
SQL_NTS,
(SQLWCHAR*)Password.getTerminatedBuffer(),
SQL_NTS);
if(SQL_SUCCEEDED(sqlRet))
{
cout << "Connection to database successful" << endl;
SQLRETURN sqlRet = SQLAllocHandle(SQL_HANDLE_STMT,
hSQLODBC,
&hSQLStatement);
if(SQL_SUCCEEDED(sqlRet))
{
sqlRet = SQLExecDirectW(hSQLStatement,
(SQLWCHAR*)SQLStatement.getTerminatedBuffer(),
SQL_NTS);
if(SQL_SUCCEEDED(sqlRet))
{
cout << "Query Execution successful" << endl;
}
else
cout << "Query Execution failed" << endl;
}
}
else
{
cout << "Connection to database failed" << endl;
}
}
return 0;
}
Подумайте, что здесь может быть неправильным?
EDIT 1: Добавлен пример кода
EDIT 2: Обновленный согласно предложению Оливера
тип данных столбца 'SAMPLE' должен быть' NVARCHAR' –
да тип данных 'NVARCHAR' – D3XT3R
Какую версию FreeTDS вы используете? 0,95, 0,91? Версия TDS версии 7.3 поддерживается только в FreeTDS 0.95. Я считаю, что 0.91 поставляется с RHEL 6, но я не уверен с RHEL 5. – FlipperPA