Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Problem bei Insert von vielen Daten in SQLite DB
simon89
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

Problem bei Insert von vielen Daten in SQLite DB

beantworten | zitieren | melden

Hi Leute,

bitte nicht verunglimpfen, ist mein erster Beitrag hier!

Ich benutzt als DBMS SQLite und die System.Data.SQLite Bibliothek

Ich hab ne in nem 2-dimensionalen string array daten liegen (ca. 400 x 25 Daten),
dass in die SQL-DB einfließen soll. Leider funktioniert das nicht so, wie ich mir das vorgestellt habe und würde gerne wissen, ob einer von euch ne idee hätte.
Im Moment pack ich ins SQL einfach nur das wort "test" wie man unten sieht

Wenn ich die ganze Sache ausführe gibts in der Zeile sqliteCmd.ExecuteNonQuery(); nen Fehler:

ArgumentNullException
Value cannot be null.
Parameter name: s

Kann mir evtl. einer helfen?

Hier erstmal der Code:


      public void executeInsertOrUpdate(string report, string[,] strArray)
        {
            using (SQLiteConnection sqliteConn = new SQLiteConnection("Data Source=" + filesource + ";Version=3;Compress=True;UTF8Encoding=True;"))
            {
                using (SQLiteCommand sqliteCmd = sqliteConn.CreateCommand())
                {
                    //open connection
                    sqliteConn.Open();

                    Stopwatch watch = new Stopwatch();

                    sqliteCmd.Transaction = sqliteConn.BeginTransaction();
                    
                    watch.Start();

                    DataTable tableInfo = sqliteConn.GetSchema("Columns", new string[] { null, null, report });

                    int i = 0;
                    foreach (DataRow column in tableInfo.Rows)
                    {
                        i++;
                        object[] test = column.ItemArray;
                        sqliteCmd.Parameters.Add(sqliteCmd.CreateParameter());
                    }
                    //insert new data
                    for (int j = 0; j < 400; j++)
                    {
                        for (int k = 0; k < strArray.GetLength(1); k++)
                        {
                            if (strArray[j, k] == null)
                            {
                                sqliteCmd.Parameters[k].Value = "test";
                            }
                            else
                            {
                                sqliteCmd.Parameters[k].Value = "test"; // "'" + strArray[j, k] + "'";
                            }

                        }
                        sqliteCmd.ExecuteNonQuery();
                    }
                    sqliteCmd.Transaction.Commit();
                    watch.Stop();
                    MessageBox.Show("Insert von 400 Elementen: " + watch.ElapsedMilliseconds.ToString() + " ms.");

                }
            }
        }
    }
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von simon89 am .
private Nachricht | Beiträge des Benutzers
Dr.Z
myCSharp.de - Member

Avatar #avatar-2603.jpg


Dabei seit:
Beiträge: 93
Herkunft: Nettetal

beantworten | zitieren | melden

Wenn mich nicht alles täuscht, dann fehlt dir dein SQL-Stament.
"Insert Into" oder "Update"
private Nachricht | Beiträge des Benutzers
phlekk
myCSharp.de - Member



Dabei seit:
Beiträge: 63

beantworten | zitieren | melden

Da fehlt definitiv das SQL Statement. Es zwar schön und sehr lobenswert das du Parameter verwendest, aber ohne SQL Statement geht es nicht.

gruß phlekk
private Nachricht | Beiträge des Benutzers
simon89
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

Ähm ja ... Shame on me ... ich hatte es einfach vergessen und mich dann noch gewundert wieso es nicht funktioniert.

Danke vielmals

Das hier fehlte:


sqliteCmd.CommandText = "INSERT INTO xxx (x,x,x,x ....) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";

400 * 23 Inserts brauchen 391 ms :)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von simon89 am .
private Nachricht | Beiträge des Benutzers
Dr.Z
myCSharp.de - Member

Avatar #avatar-2603.jpg


Dabei seit:
Beiträge: 93
Herkunft: Nettetal

beantworten | zitieren | melden

In einer Schleife die in einer Schleife läuft.
Man das auch besteimmt direkt in einem Rutsch in die DB schreiben.
Da weiß ich aber grade nicht wie. Denke, dass es dann noch schneller geht.

Dr.Z
private Nachricht | Beiträge des Benutzers
juetho
myCSharp.de - Member



Dabei seit:
Beiträge: 3358
Herkunft: Berlin

beantworten | zitieren | melden

Zitat von Dr.Z
... Man das auch besteimmt direkt in einem Rutsch in die DB schreiben.
Da weiß ich aber grade nicht wie.
Das geht eigentlich nur dann, wenn die Daten schon in einer sauberen Struktur vorhanden sind wie einer DataTable. Wenn sie aber aus einem String-Array kommen (igitt, aber wer weiß, wie das entstanden ist), dann ist dieses Vorgehen akzeptabel; die innere Schleife ordnet schließlich das "innere" Array den Spalten-Parametern zu und ist deswegen richtig.

Jürgen
private Nachricht | Beiträge des Benutzers
simon89
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

Danke für die Antwort: Ich könnte die Daten auch als DataTable verfügbar machen.

Wie wäre dann ein Insert mit dem obigen Code besser wenn ich mal so fragen darf?
private Nachricht | Beiträge des Benutzers
juetho
myCSharp.de - Member



Dabei seit:
Beiträge: 3358
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Simon,

das hängt davon ab, wie die Daten in die DataTable gelangen. Wenn es durch Rows.Add passiert, gilt immer DataRowState.Added - das ist die beste Voraussetzung (notfalls gibt es eine Methode SetAdded o.ä.). Dann kannst du einen DbDataAdapter erstellen, dazu einen InsertCommand (entweder automatisch aufgrund eines SelectCommand mit DbCommandBuilder oder manuell, was bei deiner Vorarbeit wahrscheinlich einfacher ist) und dann DbDataAdapter.Update ausführen. Die Schleife mit der Zuordnung der Parameter und Transaction geht dann sozusagen automatisch.

Ein Mini-Beispiel für den InsertCommand ist auch in [Artikelserie] Parameter von SQL Befehlen enthalten.

Gruß Jürgen
private Nachricht | Beiträge des Benutzers
simon89
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

Die Daten kommen aus einer Excelfile und würden wie folgt in eine DataTable geschrieben:


DataTable myvalues = (DataTable)range.Cells.Value2;

(Die Variable range ist vom Typ Microsoft.Office.Interop.Excel.Range)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von simon89 am .
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10076

beantworten | zitieren | melden

Und warum so umständlich?

Du kannst auch per OleDB eine Excel Tabelle in ein DataSet lesen.
private Nachricht | Beiträge des Benutzers
Xynratron
myCSharp.de - Member



Dabei seit:
Beiträge: 1184

beantworten | zitieren | melden

huhu,
Zitat von FZelle
Du kannst auch per OleDB eine Excel Tabelle in ein DataSet lesen.

Davon würde ich abraten. Wenn Excel z.B. einen EAN-Code bekommt, wird der als Wissenschaftliche Zahl formatiert. Wenn man dann per Ole-DB drauf zugreift, sagt einem Excel dass es eine Zahl ist und ruiniert bei der Übergabe den EAN. Auch Zahlen im Format "7.5" (engl. 7,5) werden reinterpretiert -> 7. Mai. Wenn es die erste Zahl in der Sheet-Spalte ist, dann wird ein Datentyp Date angenommen (und alle anderen Zahl die nicht als Datum interpretierbar sind werden aus dieser Spalte verworfen) oder umgekehrt, die falsch interpretierten "Datumswerte" werden verworfen (Weil z.B. die erste Zahl eine 7.0 war).

Das sind Infos die ich nur aus Programmteilen von Kollegen (da die resultierenden Fehler auf meinen Schreibtisch kamen) kenne. Wenn jemand dafür eine "einfache" Lösung mit OleDB hat wär ich dankbar. Ich hab jedenfals bis auf weiteres Excel-InterOp vorgegeben. Das funktioniert soweit wenigstens.

:-)

Xynratron
Herr, schmeiss Hirn vom Himmel - Autsch!
Zitat von herbivore
Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10076

beantworten | zitieren | melden

Deshalb fragte ich ja.

Manchmal gibt es den einfachen weg nicht.
Nur meist sind es nur normale Daten, und die gehen dann so einfacher.

Wobei ich würde im Professionellen Umfeld dann eher etwas wie
http://www.gemboxsoftware.com/Spreadsheet/Pricelist.htm
oder
https://www.spreadsheetgear.com/downloads/purchase.aspx

Letzteres gibt/gab es übrigens mal kostenlos wenn man sich als 2005 Express Besitzer
Registriert hat.
private Nachricht | Beiträge des Benutzers
simon89
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

Ich habe es mit Excel.Interop gemacht und das funktioniert super und daher möchte ich es gar nicht ändern.

Außerdem war dies nicht das Thema, sondern wie man aus dieser DataTable heraus in meinem obigen Code am besten die Daten in eine sqlite Datenbank einfügt.

Gruß Simon
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von simon89 am .
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10076

beantworten | zitieren | melden

Natürlich ist das auch eine Frage.
Denn wenn Du die Daten per OleDB gelesen hättest, hättest du im DataAdapter
erst einen Parameter setzen müssen.

Und das mit dem Update einer DataTable in eine DB steht in jeder ADO.NET Einleitung.
Das ist mit jedem DataAdapter gleich.
private Nachricht | Beiträge des Benutzers
simon89
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

Ok danke

private Nachricht | Beiträge des Benutzers