MS ODBC encoding issue
Nathan M. Swan
nathanmswan at gmail.com
Tue Dec 4 02:05:15 PST 2012
On Tuesday, 4 December 2012 at 07:59:40 UTC, Sam Hu wrote:
> Greetings!
>
> Any help would be much appreicated in advance as I've really
> struggled for quite long time!
>
> I wrote a class wrapper for MS ODBC Access database.When I try
> to run query on an Access database file,all fields contains
> English character are fine with the result,but for those Asian
> characters like Chinese,the result shows blank in DFL gui form
> and shows mess (unrecognizable under console).I think maybe the
> problem is in the fetchAll function which I provided as below
> together with the other main parts of the class:
> Client code (DFL form):
> [code]
> protected void onReadClick(Object sender,EventArgs e)
> {
> Odbc odbc=new Odbc;
> odbc.connect("artistdb","","");
> if(!odbc.isOpen)
> {
> throw new Exception("Failed to connect to ODBC");
> return;
> }
> auto record=odbc.fetchAll("select * from artists where
> artistid="~txtSearch.text~";");
> txtID.text=to!string(record[0][0]);
> txtName.text=to!string(record[0][1]);
> odbc.close;
> }
> [/code]
>
> ODBC wrapper class:
> [code]
> SQLRETURN SQLExecDirectUTF8(SQLHSTMT stmt,string
> text,SQLINTEGER tl)
> {
> SQLRETURN retcode;
> //uint16* utf16=UTF8toUTF16(text,null);
>
> retcode=SQLExecDirectW(stmt,cast(SQLWCHAR*)toUTF16z(text),tl);
>
> return retcode;
>
> }
> string[][] fetchAll(const char* pszSql)
> {
> string[][] v;
>
> if(pszSql is null )
> return null;
> retCode=SQLExecDirectUTF8(hStmt,to!string(pszSql),SQL_NTS);
> if((retCode != SQL_SUCCESS) && (retCode !=
> SQL_SUCCESS_WITH_INFO))
> {
> throw new Exception(format("Error AllocHandle with
> retCode: %d",retCode));
> return null;
> }
>
> retCode=SQLNumResultCols(hStmt,&col);
> if((retCode != SQL_SUCCESS) && (retCode !=
> SQL_SUCCESS_WITH_INFO))
> {
> throw new Exception(format("Error AllocHandle with
> retCode: %d",retCode));
> return null;
> }
> row=0;
> SQLINTEGER colLen = 0;
> SQLSMALLINT buf_len = 0;
> SQLINTEGER colType = 0;
>
> while(true)
> {
> char sz_buf[256];
> char* pszBuf;
> SQLINTEGER buflen;
> string[] rowData=new string[col+1];
>
> if(SQLFetch(hStmt)==SQL_NO_DATA)
> {
> break;
> }
> for(int i=1;i<=colCount;i++)
> {
> SQLColAttribute(hStmt, cast(ushort)i, SQL_DESC_NAME,
> sz_buf.ptr, 256, &buf_len, cast(void*)0);
> SQLColAttribute(hStmt, cast(ushort)i, SQL_DESC_TYPE,
> cast(void*)0, 0, cast(short*)0, &colType);
> SQLColAttribute(hStmt, cast(ushort)i,
> SQL_DESC_LENGTH, null, 0, cast(short*)0, &colLen);
> pszBuf=cast(char*)(new char[colLen+1]);
> //pszBuf[0]='\0';
>
> SQLGetData(hStmt,cast(ushort)i,SQL_C_CHAR,pszBuf,50,cast(int*)&buflen);
> pszBuf[buflen]='\000';
> rowData[i-1]=to!string(pszBuf);
>
>
> }
> v~=rowData;
> row++;
>
> }
> SQLCancel(hStmt);
> return v;
> }
> string[][] fetchAll(string sql)
> {
>
> return fetchAll(sql.ptr);
> }
> [/code]
I've never used ODBC before, but a quick scan of the MSDN docs
suggests that you should use SQL_C_WCHAR instead, maybe using
some D wstring functions too.
BTW, convert sql.ptr -> std.string.toStringz(sql); this is good
practice, though I'm not sure it's your problem.
NMS
More information about the Digitalmars-d-learn
mailing list