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

Reply via email to