Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why MS access odbc returns numbers but no strings in C#?

I'm using an ODBC connection to fetch data from an Access file (.mdb) in a Unity3D environment (Mono.net) on Windows 7 and the connection, deconnection and requests happen without any error.

But when I read the data I get, I only receive the numbers from the database. It can be Integers, or Float numbers. But when I try to fetch a string, it always return an empty string.

Here is what I use in my DataBaseHandler class to perform requests (extracts) :

public ArrayList Execute(string req)
{
ArrayList output = new ArrayList();

[...]

cmd = new OdbcCommand(req);
cmd.Connection = accessConnection;

OdbcDataReader reader = cmd.ExecuteReader();
while (reader.Read()) {
    String[] row = new String[reader.FieldCount];

    for (int i=0; i<reader.FieldCount; i++) {
        if (!reader.IsDBNull(i)) { // Added if for Visual Studio
            // Getting empties strings, but work fine with numbers
            row[i] = reader.GetValue(i).ToString(); 
            // I was using GetString before, but didn't work with Visual Studio
        }
    }

    output.Add( row );
}

[...]
return output;
}

And this is what I perform to test the request :

ArrayList data = db.Execute("SELECT * FROM Materials");

foreach (String[] row in data) {
    string line = "";
    foreach (String s in row) {
        line += s + " - ";
    }
    Debug.Log(line); // Logging in Unity3D console
}

And I'm getting :

1234 - 23.1 - - -
5678 - 12.9 - - -

Instead of :

1234 - 23.1 - A string - Another string -
5678 - 12.9 - Hello - World -

Why am I getting only numbers and no strings and how can I correct it ?

EDIT : It work fine with Visual Studio 12, and Windows 7, and the edits I had to make for making it work with Visual Studio didn't show any improvement in my Unity program.

like image 226
Dean Avatar asked May 29 '15 14:05

Dean


People also ask

Which driver is used for MS Access?

Microsoft Access is well-suited both for individuals and small businesses. Devart ODBC drivers that support all modern versions of Microsoft Access allow accessing databases, services, and clouds applications.


1 Answers

I have to start by saying that I don't have an environment to reproduce this; my answer is very much based on what I have expended in C# on Windows with SQL Server; namely that the buffers used underneath the DataReader get reused for memory efficiency.

When the numbers are converted to strings, memory MUST be allocated for the string, since no string currently exists. When the ToString is run on an actual string, you are probably getting a reference to a string still buried deep within the DataReader. That memory then gets reused by the next record.

The basic solution is to either do your processing on a record by record basis, or make copies of everything you need as you loop around.

like image 137
dsz Avatar answered Sep 19 '22 14:09

dsz