none
Different result with arabic characters between DBDatareader and Recordset RRS feed

  • Question

  • HI,

    I have a strange problem when trying to read arabic values in a DB2 database with DbDataReader with ADO .NET and also after that with Recordset object coming from ADODB 2.8.

    With DbDataReader I receive garbage values : " Âú´ï´ß[ ÂÍú["

    With Recordset I receive the correct arabic values : " ةينانبل ةريل"

    Of course I am using the same connection string and the same query.

    The driver is an ODBC driver (IBM Client Access).

    Somebody to explain this different behavior with these 2 methods ?

    Thanks a lot

    Wednesday, January 26, 2011 10:44 AM

Answers

  • Hello Cook32,

     

    Thank you for posting here.

    I think we can learn this part together. Here is the difference between RecordSet and DataReader:

    The Recordset can leverage server cursors and do what it is supposed to do being connected to the data source all the time. At the same time, another facet of the same object can work disconnected and build up a correct representation of records in two ways. Either it can fetch rows from the data source and then drop the connection, or it can read all the needed information from a client disk file, including an XML file with a fixed schema.

    The disconnected facilities of ADO have been bolted on the Recordset object interface, paying careful attention to make connected and disconnected functionalities available through equivalent APIs. As a result, the Recordset became hard to wield, rather overwhelming and with significant housekeeping.

    Whatever way you work, you always use the Recordset object and choose the operating mode by selecting the proper cursor type and location. (See the ADO documentation for more details.)

    An obvious drawback is that no matter how optimized and well-designed the Recordset object is, you load in memory more stuff than you actually need. In addition, it adds an extra layer of code to process input parameters and possibly fixes their values. Given the overall programming interface of ADO, this is an absolute necessity as well as a performance hit.

    The DataReader object is the ADO.NET counterpart of the read-only, forward-only default ADO cursor. The DataSet is a container that can be programmatically filled with static snapshot of data. In this sense, it can be seen as a repository of disconnected recordsets. There's no Recordset component in the ADO.NET object model, but the DataTable object is the .NET double of a disconnected recordset.

    Here is an old article about this.

    http://msdn.microsoft.com/en-us/library/ms810288.aspx

    I hope it can help you,

     

    Have a nice day,


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, January 27, 2011 3:16 AM
    Moderator

All replies

  • Hello Cook32,

     

    Thank you for posting here.

    I think we can learn this part together. Here is the difference between RecordSet and DataReader:

    The Recordset can leverage server cursors and do what it is supposed to do being connected to the data source all the time. At the same time, another facet of the same object can work disconnected and build up a correct representation of records in two ways. Either it can fetch rows from the data source and then drop the connection, or it can read all the needed information from a client disk file, including an XML file with a fixed schema.

    The disconnected facilities of ADO have been bolted on the Recordset object interface, paying careful attention to make connected and disconnected functionalities available through equivalent APIs. As a result, the Recordset became hard to wield, rather overwhelming and with significant housekeeping.

    Whatever way you work, you always use the Recordset object and choose the operating mode by selecting the proper cursor type and location. (See the ADO documentation for more details.)

    An obvious drawback is that no matter how optimized and well-designed the Recordset object is, you load in memory more stuff than you actually need. In addition, it adds an extra layer of code to process input parameters and possibly fixes their values. Given the overall programming interface of ADO, this is an absolute necessity as well as a performance hit.

    The DataReader object is the ADO.NET counterpart of the read-only, forward-only default ADO cursor. The DataSet is a container that can be programmatically filled with static snapshot of data. In this sense, it can be seen as a repository of disconnected recordsets. There's no Recordset component in the ADO.NET object model, but the DataTable object is the .NET double of a disconnected recordset.

    Here is an old article about this.

    http://msdn.microsoft.com/en-us/library/ms810288.aspx

    I hope it can help you,

     

    Have a nice day,


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, January 27, 2011 3:16 AM
    Moderator
  • Hello Jackie,

     

    Thanks a lot for your answer.

    I already read this article. But it is interesting of course to see the difference between the different way of work.

    But it does not explain why my output is different in both ways.

    Here are my piece of code :

     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.Common;
    using ADODB;

     

    private void DbReaderMod()

    {

                DbConnection dbConnection = DbProviderFactories.GetFactory("System.Data.Odbc").CreateConnection();
                DbConnectionStringBuilder Stringreader = new DbConnectionStringBuilder();
                Stringreader.ConnectionString = "Provider=MSDASQL.1;Persist Security Info=False;Data Source=CA_ODBC;Extended Properties=\"DSN=CA_ODBC;\";Initial Catalog=S6559BF2;TRANSLATE=1";
                object s;
                DbConnectionStringBuilder builder = DbProviderFactories.GetFactory("System.Data.Odbc").CreateConnectionStringBuilder();
                Stringreader.TryGetValue("Data Source", out s);

                builder.Add("DSN", s);
               
                if (Stringreader.TryGetValue("Provider", out s))
                    builder.Add("Provider", s);
                if (Stringreader.TryGetValue("Initial Catalog", out s))
                    builder.Add("Initial Catalog", s);
                if (Stringreader.TryGetValue("Integrated Security", out s))
                    builder.Add("Integrated Security", s);
                if (Stringreader.TryGetValue("User Id", out s))
                    builder.Add("uid", s);
                if (Stringreader.TryGetValue("Password", out s))
                    builder.Add("pwd", s);


                dbConnection.ConnectionString = builder.ConnectionString;


                dbConnection.Open();
                DbCommand cmd = dbConnection.CreateCommand();
               
                cmd.CommandText = "SELECT \"BAREP\".\"A3TX\" FROM \"ZBLOMDTA\".\"BAREP\" \"BAREP\"";
                DbDataReader reader = cmd.ExecuteReader();
               
                reader.Read();
                for (int i = 0; i < 10; i++)
                {
                    string val = reader.GetValue(0).ToString();             
                   
                }
                reader.Close();
                dbConnection.Close();

            }

    private void RecordSetMethod()

    {

               Recordset oRecordset = new Recordset();

                ADODB.Connection vConnection = new ADODB.Connection();
               

                vConnection.Open("Provider=MSDASQL.1;Persist Security Info=False;Data Source=CA_ODBC;Extended Properties=\"DSN=CA_ODBC;\";Initial Catalog=S6559BF2","USERID1","PWD1");


                string vSource = "SELECT \"BAREP\".\"A3TX\" FROM \"ZBLOMDTA\".\"BAREP\" \"BAREP\"";
                int lOption = (int)CommandTypeEnum.adCmdText;
                try
                {

                    oRecordset.Open(vSource, vConnection, CursorTypeEnum.adOpenForwardOnly, LockTypeEnum.adLockReadOnly, lOption);
                }
                catch (Exception ex)
                {
                  
                    throw ex;
                   
                }

                for(int i=0;i<10;i++)
                {
                    string val = oRecordset.Fields[0].Value.ToString();
                    byte[] tab = Encoding.Default.GetBytes(val);

                    oRecordset.MoveNext();
                }

                oRecordset.Close();
                vConnection.Close();
            }
        }
    }

    So DbReaderMethod gives me garbage values in val string and the RecordsetMethod gives me the good arabic characters...

    Strange...

     

    Thanks for your help

    Cook32

    Thursday, January 27, 2011 7:59 AM
  • Hello Cook32,

    Thanks for your feedback.

    By reading your code, I've found some problem.

    Could you please tell me what's the meaning of "byte[] tab = Encoding.Default.GetBytes(val);" and would it lead to this difference in your thread ?

    And more, I found that usually we use DataReader like this:

    while (reader.Read())
                {
                    Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
                        reader.GetString(1));
                }
    And about DbReader it advances the SqlDataReader to the next record. So please check you code.

     

    Good day,


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, February 1, 2011 7:56 AM
    Moderator