Laden...

Mehrzeilige Zelle in einem DataSet

Erstellt von chanderegg vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.258 Views
C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 14 Jahren
Mehrzeilige Zelle in einem DataSet

verwendetes Datenbanksystem: Oracle 10 + Sql 2005

Hallo zusammen

Ich hab ein Programm, welches auf Oracle und Sql laufen muss. Nun fülle ich Daten mit einem DbDataReader in die Datensets ab. Dies hat eigentlich sehr gut funktioniert. Nun habe ich aber auf der DB eine Spalte vom Typ Long.

Wenn ich die auslese, sehe ich im DataReader, dass es ein mehrzeiliger String ist. Wenn ich diesen aber dem DataSet zuweise, so ist nur die erste Zeile im DataSet.

Kann mir jemand von euch sagen, wie ich es schaffe, dass der ganze String ins DataSet kommt?

Hier mein Code:


            string query = @"select * from mg001 order by mgspr, mgnbr";

            myConnection = AGB70.PABS.Common.Var.gblDBInfo.GetDbConnection();
            myConnection.Open();

            myCommand = AGB70.PABS.Common.Var.gblDBInfo.GetDbCommand(query, myConnection);
            myReader = myCommand.ExecuteReader();

            MG001DataSet aDataSet = new MG001DataSet();

            while (myReader.Read())
            {
                MG001DataSet.MG001Row row = aDataSet.MG001.NewMG001Row();

                row.MGSPR = myReader[0].ToString();
                row.MGNBR = myReader[1].ToString();
                row.MGKTX = myReader[2].ToString();
                row.MGLTX = myReader[3].ToString();  //Dieser String ist mehrzeilig

                aDataSet.MG001.AddMG001Row(row);
            }

            return aDataSet;

Vielen Dank für Eure Hilfe

J
3.331 Beiträge seit 2006
vor 14 Jahren

Hallo,

unter :rtfm: OracleType-Enumeration lese ich:

LongVarChar
Ein Oracle-LONG-Datentyp, der eine Zeichenfolge mit variabler Länge und einer Maximalgröße von 2 Gigabyte enthält. Verwenden Sie in Value den .NET Framework-String-Datentyp oder den OracleClient-OracleString-Datentyp.

Also musst du es natürlich als String übernehmen. Das machst du ja, auch wenn das ToString beim Reader eher seltsam aussieht (aber dazu unten mehr). Der Wert kommt damit in der DataTable wirklich als String an, und zwar in der tatsächlichen Länge.

Kann mir jemand von euch sagen, wie ich es schaffe, dass der ganze String ins DataSet kommt?

Woran glaubst du zu erkennen, dass nur ein Teil in der DataTable landet? DataGridView, Debugger oder was auch immer? Nach deinem Code wird immer der ganze String geliefert.

Die Probleme lösen sich vielleicht auf, wenn du Datenbank und DataSet so verbindest, wie es gedacht ist. Du hast Alternativen:
* Benutze für das Ziel "DataTable" nicht ExecuteReader, sondern DbDataAdapter.Fill.
* Oder benutze DataTable.Load(myReader).
Auf jeden Fall solltest du nicht alle Daten per ToString übernehmen, sondern die korrekte Get-Methode.

Zusätzlich weise ich dich auf [Artikel] Ressourcen schonen - Datenbanken richtig öffnen und schließen hin. Dein Code sieht so aus, als ob du eine dauerhafte Connection benutzt, das wäre sehr schlecht.

Gruß Jürgen

3.825 Beiträge seit 2006
vor 14 Jahren

Hallo chanderegg,

ich verstehe den Sinn Deines Programmes nicht so ganz. Du weisst dass Du mit einem Befehl (ds.Fill) die Daten aus der Datenbank in das Dataset laden kannst ?

Beispiel : http://www.seven-c.de/files/datenbankenhowto.htm#5 Kapitel 6

Ich arbeite viel mit mehrzeiligen Datenbankinhalten, hat bei mir bisher immer funktioniert.

Guck Dir im Debugger an wo Deine Zeilenumbrüche verlorengehen :

string a1 = myReader[3].ToString();

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 14 Jahren

@juetho: habe vergessen die Verbindung zu schliessen. Danke für den Hinweis.
Wenn ich beim Debugen das DataSet anschaue, so fehlen die Zeilen.

Das Problem ist, dass ein DataTableAdapter nicht Datenbank unabhänging sein kann. Das heisst, dass wenn ich ein DataTableAdapter für Oracle erstelle, so werden im Designer OracleConnection, OracleCommand und OracleReader verwendet.

Wenn aber ein Kunde mit SQL arbeiter so funktioniert es nicht. Deshalb lade ich die Daten 'von Hand' ins DataSet.

Die Methode .Load sah vielversprechend aus. Leider werden auch dort nur die ersten Zeilen übernommen.



            string query = @"select * from mg001 order by mgspr, mgnbr";

            myConnection = AGB70.PABS.Common.Var.gblDBInfo.GetDbConnection();
            myConnection.Open();

            myCommand = AGB70.PABS.Common.Var.gblDBInfo.GetDbCommand(query, myConnection);
            myReader = myCommand.ExecuteReader();

            MG001DataSet aDataSet = new MG001DataSet();

            aDataSet.Load(myReader, LoadOption.OverwriteChanges, aDataSet.MG001);

            myConnection.Close();

            return aDataSet;


@BerndFfm
Ich habe mehrmals kontrolliert, wo die Umbrüche verloren gehen. Sie gehen verloren, wenn ich sie der Spalte übergebe. Der String selber hat die Umbrüche.
Ausserdem gehen nicht nur die Umbrüche verloren, sondern alle restlichen Zeilen. Das heisst, ich habe danach nur noch die erste Zeile

3.825 Beiträge seit 2006
vor 14 Jahren

Auch wenn ich Deine Vorgehensweise immer noch nicht verstehe probier mal :

row.MGLTX = (string)myReader[3];  //Dieser String ist mehrzeilig

Das Problem ist, dass ein DataTableAdapter nicht Datenbank unabhänging sein kann. Das heisst, dass wenn ich ein DataTableAdapter für Oracle erstelle, so werden im Designer OracleConnection, OracleCommand und OracleReader verwendet

Doch !

DbDataAdapter, DbConnection und DbCommand sind datenbankunabhängig. Wie das mit Designer und Assistenten tut weiss ich nicht, ich nutze das nicht sondern schreibe meinen Code immer selber.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 14 Jahren

Das heisst, wenn du im Visual Studio ein neues DataSet erstellst, schreibst du jede Zeile selber??? respekt.

Wenn ich also im Deigner alle Oracle Connections auf DbConnections umstelle und denen die richtigen Objekte zuweise, sollte das also Db unabhängig sein?

Bin gerade ein wenig frustriert. Hatte den Auftrag ein Programm auf SQL und Oracle lauffähig zu machen und habe alle TableAdapter gelöscht und von Hand abgefüllt.

J
3.331 Beiträge seit 2006
vor 14 Jahren

@Bernd
Er hat recht, das Code-Monster TableAdapter bezieht sich auf eine DbConnection usw. Das ist natürlich ein Grund mehr, auf das, was der Designer macht und versteckt, zu verzichten.

@chanderegg
Du kannst trotzdem DbDataAdapter.Fill verwenden, wie es Bernd vorschlägt. - Es genügt nicht, die DbConnection per Close zu schließen, sondern sie soll auch per Dispose aufgelöst werden. Besser noch: man kapselt sie in einem using-Block, dann geht beides automatisch.

Aber das hat mit dem Problem nichts zu tun. Bernd hatte schon vorgeschlagen, den String selbst (Variable a1) zu untersuchen. Wie wird dort eine Zeile beendet? Environment.NewLine? Nur '\r'? Nur '\n'? Oder etwa '\0' (wer weiß denn, woher der String ursprünglich kommt)? Letzteres wäre eine Erklärung für das Abschneiden des restlichen Textes. Benutze doch mal IndexOfAny oder so.

Jürgen

3.825 Beiträge seit 2006
vor 14 Jahren

Das heisst, wenn du im Visual Studio ein neues DataSet erstellst, schreibst du jede Zeile selber???

Ich benutze untypisierte Datasets, da schreibe ich keine einzige Zeile selbst. Die haben dafür andere Nachteile.

Typisierte Datasets sind meines Wissens aber auch nicht von der Datenbank abhängig.

Wenn ich also im Deigner alle Oracle Connections auf DbConnections umstelle und denen die richtigen Objekte zuweise, sollte das also Db unabhängig sein?

Ja genau. Das kann dann so aussehen :

public DbConnection CreateConnection()
{
	DbConnection conn = null;
	if (dbprovider == Parameter.DatenbankProvider.SQLServerCompactEdition) conn = new SqlCeConnection();
	if (dbprovider == Parameter.DatenbankProvider.MySQL) conn = new MySqlConnection();
	if (dbprovider == Parameter.DatenbankProvider.OracleSQLServer) conn = new OracleConnection();
	if (dbprovider == Parameter.DatenbankProvider.OleDB) conn = new OleDbConnection();
	if (dbprovider == Parameter.DatenbankProvider.PostgreSQL) conn = new NpgsqlConnection();
	conn.ConnectionString = connStr(dbprovider, server, database);
	return conn;
}

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

J
3.331 Beiträge seit 2006
vor 14 Jahren

Ergänzung zu Bernd:

So ungefähr geht es dann weiter:

DbCommand cmd = conn.CreateCommand();
...
conn.Dispose();

Alles, was mit einer Create-Methode erzeugt wird, ist dann Instanz einer passenden Klasse.

Gruß Jürgen