dotnet-snippets.de
Willkommen bei dotnet-snippets.de! Snippet hinzufügen Login Registrieren
Snippets in der Datenbank: 1405 | Anzahl registrierter User: 1436 | Besucher online: 221
Hauptmenü
Home
Top Ten
Zufälliger Snippet
Tech-Ed-Gewinnspiel
FAQs
.NET Community
dotnet-forum.de
dotnet-kicks.de
Social

RSS Feeds
Rss Alle Snippets
Rss C#
Rss VB.NET
Rss C++
Rss ASP.NET
Partner
Partner von Codezone.de


Member of Microsoft Community Leader/Insider Program (CLIP)

Währungskurse in Datenbank speichern


Autor: knoyxz
Sprache: C#
Bewertung: 2,6
(1 Bewertung)

Anzahl der Aufrufe: 5542
  

Beschreibung:

Hallo :-)

Unter http://www.ecb.europa.eu/stats/exchange/eurofxref/html/index.en.html#dowloads
sind Währungskurse von 1999 bis heute als XML-Dateien verfügbar.

Mit dieser Methode könnt Ihr diese Daten auslesen und in eine Datenbank speichern.

Die Tabelle der Datenbank enthält drei Spalten:
Datum (Datetime),
Waehrung (nchar(3)),
Kurs (decimal(18,4))

Ganz unten findet Ihr ein Beispiel wie diese Methode aufgerufen werden könnte.


Abgelegt unter: Währungskurs, XML, Datenbank, Währung, Wechselkurs.



C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//using System;
//using System.Data;
//using System.Data.SqlClient;
//using System.Net;
//using System.Xml;

private void WaehrungsKursInDatenbankSpeichern(String urlDerXML, String zielTabelle, SqlConnection con)
{
    XmlTextReader xmlReader;

    DataTable dtWechselkurs = new DataTable();
    dtWechselkurs.Columns.Add(new DataColumn("Datum",System.Type.GetType("System.DateTime")));
    dtWechselkurs.Columns.Add(new DataColumn("Waehrung", System.Type.GetType("System.String")));
    dtWechselkurs.Columns.Add(new DataColumn("Kurs", System.Type.GetType("System.Decimal")));

    try
    {
        //XML-Daten übers Internet einlesen
        xmlReader = new XmlTextReader(urlDerXML);
    }
    catch( WebException )
    {
        throw new WebException("Währungsdaten konnten nicht abgerufen werden!");
    }

    try
    {
        DateTime tempDatum = DateTime.Now;
        String tempWaehrung;
        Decimal tempKurs;

        while (xmlReader.Read())
        {
            if (xmlReader.Name != "")
            {

                for (int i = 0; i < xmlReader.AttributeCount; i++)
                {
                    //Prüfen ob es den Knoten/Element 'Cube' gibt
                    if (xmlReader.Name == "Cube")
                    {
                        //Falls der Knoten/Element nur 1 Attribut enthält, ist dies das Datum
                        if (xmlReader.AttributeCount == 1)
                        {
                            //Datum auslesen
                            xmlReader.MoveToAttribute("time");
                            tempDatum = DateTime.Parse(xmlReader.Value);
                        }
                        //Sind 2 Attribute im aktuellen Knoten/UnterElement, enthält dieser WährungsKürzel und Kurswert
                        if (xmlReader.AttributeCount == 2)
                        {
                            //Währung auslesen
                            xmlReader.MoveToAttribute("currency");
                            tempWaehrung = xmlReader.Value;

                            //Kurs auslesen
                            xmlReader.MoveToAttribute("rate");
                            tempKurs = decimal.Parse(xmlReader.Value.Replace(".", ",")); // Komma als DecimalSymbol
                            
                            //ausgelesene Werte zusammen in einer neuen Zeile eintragen
                            DataRow neueZeile = dtWechselkurs.NewRow();
                            neueZeile["Datum"] = tempDatum;
                            neueZeile["Waehrung"] = tempWaehrung;
                            neueZeile["Kurs"] = tempKurs;

                            dtWechselkurs.Rows.Add(neueZeile); 
                        }

                        xmlReader.MoveToNextAttribute();
                    }
                }
            }
        }
        //Verbindung zur Datenbank herstellen
        con.Open();

        //Alle Kurse wurden in dtWechselkurs eingefügt und werden jetzt an die Datenbank geschickt
        SqlBulkCopy bcopy = new SqlBulkCopy(con);
        bcopy.DestinationTableName = zielTabelle;
        bcopy.WriteToServer(dtWechselkurs);
        con.Close();
        MessageBox.Show("Währungskurs erfolgreich eingefügt");
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message,"Währungskurs konnte nicht importiert werden");
    }
}


//es folgt ein Beispiel zum Aufruf der Methode
private void BeispielAufruf_WährungSpeichern(object sender, EventArgs e)
{
    String urlDerXML = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml";
        //folgende Kursdaten sind verfügbar:
        //Kurse von heute = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"
        //letzten 90 Tage = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml";
        //Kurse seit 1999= "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml";


    String zielTabelle = "Wechselkurs";

    //Verbindungsaufbau definieren
        SqlConnectionStringBuilder conBuilder = new SqlConnectionStringBuilder();
        conBuilder.DataSource = "(local)";        //kann auch eine IP oder Name sein, dann ohne Klammern
        conBuilder.InitialCatalog = "knoxyz";
        conBuilder.ConnectTimeout = 10;
        conBuilder.IntegratedSecurity = true; //oder User & Password
        //conBuilder.UserID = "knoxyz";
        //conBuilder.Password = "xyz";
        SqlConnection con = new SqlConnection(conBuilder.ConnectionString);
    
   
    WaehrungsKursInDatenbankSpeichern(urlDerXML,zielTabelle,con);
}
Sie haben Fragen zu diesem Snippet oder brauchen Hilfe bei der .NET Entwicklung?
Freundliche und kompetente Entwickler helfen Ihnen gern weiter im Forum für .NET Entwicklung.



Kommentare:
(Zum Schreiben von Kommentaren bitte anmelden.)

knoyxz schrieb am:  24.11.2008 08:21:21

Warum denn diese Bewertung (2,6)?
Falls jemand einen effektiv eren Weg findet,
Währungsdaten in eine Datenbank zu bekommen,
kann er mir dies sehr gern mitteilen.

Für mich ist dieser Schritt wirklich wichtig,
um in einheitlicher Währung, eine Bestellübersicht von offene/abgeschlossene Positionen zu erhalten die international (in verschiedenen Währungen) getätigt wurden.

knoxyz
Günther Foidl schrieb am:  24.11.2008 11:28:17

Einige Anmerkungen zum Code:
1) die Verbindung wird nicht geschlossen
2) die Ressourcen werden nicht freigegeben -> verwende dazu am besten using (...)
3) besser wäre auch im DataTable den Spaltentyp auch anzugeben
4) effizienter ist bei decimal.Parse im String nicht den (.) durch (,) zu ersetzten denn das ist eine String-Operation und die ist aufwändig. Stattdessen die invariante Kultur verwenden, dort ist der (.) das Dezimaltrennzeichen.
decimal kurs = decimal.Parse(string, System.Globalization.NumberForamtInfo.InvariantInfo);

5) funktioniert (bei mir) nicht da beim BulkCopy ein Fehler geworfen wird dass "Der angegebene Wert vom Typ String aus der Datenquelle kann nicht in Typ datetime der angegebenen Zielspalte konvertiert werden."
6) kann mit LINQ eleganter gelöst werden (was effizienter ist weiß ich nicht)

private static void KursXML2DB(string url, KursDataContext db)
{
XElement xml = XElement.Load(url).Element("Cube");
var xmlKurse =
from k1 in xml.Elements()
from k2 in k1.Elements()
select new Kurs
{
Datum = DateTime.Parse(k1.Attribute("time").Value),
Währung = k2.Attribute("currency").Value,
Kurs1 = decimal.Parse(k2.Attribute("rate").Value, NumberFormatInfo.InvariantInfo)
};

db.Kurs.InsertAllOnSubmit(xmlKurse);
db.SubmitChanges();
db.Dispose();
}
knoyxz schrieb am:  25.11.2008 21:37:25

Hallo Günther,

habe ebenfalls einige Hinweise zu deinen Anmerkungen:
1) Die Verbindung wird nie, bzw. nur durch TimeOut, geschlossen. Ein con.Close() ist lediglich der Optik schön. Tatsächlich bleibt die Verbindung jedoch im Connection-Pool weiterhin geöffnet.

2) Ressourcen könnten wirklich freigegeben werden, ist bei der geringen Menge an Daten jedoch nicht nötig

3) DatenTyp im DataTable zu definieren ist tatsächlich Sinnvoll, leider habe ich es auch nach einigen ausprobieren nicht geschafft. Für ein Beispiel währe ich dankbar.

4) Hier liegst du leider daneben, dass Komma muss sein wenn nicht alles mit 1000 multipliziert werden soll! Du rufst die kulturunabhängige Formatierung (entspricht die amerikanische) Formatierung auf.
Richtig ist:
decimal kurs = decimal.Parse(String, System.Globalization.NumberFormatInfo.CurrentInfo);


5) Kann die Fehlermeldung leider nicht reproduzieren. Hast du dein System evtl. auf eine englische Länderkennung eingestellt?

6) In unserem Unternehen ist bisher nur .Net 2.0 vorhanden und so LINQ nicht verfügbar.

PS: Danke für deine begründete Bewertung ;-)
knoxyz
knoyxz schrieb am:  25.11.2008 21:57:01

Der Punkt 4, Datentyp für Spalten im DataTable festlegen, ist nun im Code enthalten.
Günther Foidl schrieb am:  25.11.2008 22:09:44

1) Connection: Genau aus diesem Grund sollte die Verbindung wieder in den Pool mit Close() zurückgelegt werden. Sonst könnte es passieren dass der Pool erschöpft wird und somit neue Verbindungen geöffnet werden müssen.
2) Mit der InvariantInfo liege ich genau richtig. Die Daten haben als Dezimaltrennzeichen einen (.). Dieser wird bei der Invarianten Kultur - wie du richtig angemerkt hast - auch verwendet und somit stimmt das Parsen. Bei der von dir vorgeschlagenen CurrentInfo wäre das auf einem deutschsprachigen System ein (,) und das Ergebnis wäre um den Faktor 10E3 falsch. Probiers und du wirst es sehen dass ich richtig liege.
3) Fehler: ich hab Deutsch/Österreich - ist aber nebensächlich
4) Ich hab noch gar nicht angemerkt dass mir das Snippet sonst gut gefällt!

mfG Günther
knoyxz schrieb am:  25.11.2008 22:39:12

Hi

ok, mit dem 'CurrentInfo' lag ich jetzt wirklich falsch!
Hab eben dein 'InvariantInfo' und das 'replace' ausprobiert, funktioniert beides.

Die Ursache für deine Fehlermeldung konnte ich nun wahrscheinlich ausfindig machen.
Liegt sicher daran, dass du eine andere Spaltenreichenfolge in der Tabelle hast, oder?
Sollte, wie im DataTable, erst 'Datum', 'Währung' und dann 'Kurs' sein.

Schöne Grüße
knoxyz
Günther Foidl schrieb am:  25.11.2008 22:43:24

Meine Tabelle ist:

CREATE TABLE Wechselkurs
(
Datum datetime,
Waehrung nvarchar(10),
Kurs money
);

Ich prüfe das nochmal.

mfG Günther


Diese Snippets könnten für Sie interessant sein:
[C#] Treeview in XML schreiben
[C#] Objekt in XML speichern (Serialisieren)
[ASP.net] XML - HTML Transformation
[C#] Generische XML-Serialisierung
[C#] CSV und XML-Datei Datenbank-Import (incl. valid-check)
[VB.NET] Einfaches Erstellen einer XML Datei in .Net
[C#] XML in DataTable laden
[C#] Intellisense Unterstützung für XML Dateien für LINQ
[C#] user.config und generische Listen
[C#] Dataset verschlüsseln
[C#] Xml Datei entschlüsseln
[VB.NET] Objekt mit dem XmlSerializer serialisieren
[VB.NET] XML Datei mit dem XmlSerializer deserialisieren
[ASP.net] XML Daten über einen Internet Proxy abfragen
[C#] XML-Programmkonfiguration / -Steuerung
[C#] Formatieren von Sonderzeichen für XML
[C#] Binärdatei in XML File speichern
[C#] Binärdatei aus XML Datei auslesen und abspeichern
[C#] leere Knoten aus XML Document entfernen
[C#] XML Kommentare entfernen
[C#] Austauch von kritischen Zeichen in einem String...
[C#] Excel-Export ohne Excel (auch für Web)
[C#] Ini-Datei-Klasse
[C#] TreeView Export To Xml OR Import from XMl
[C#] Autom. Laden & Speichern von Position und Größe eines Forms
[VB.NET] Bild als XML Datei Speichern
[C#] Ein Object serialisieren
[C#] Ein Object deserialisieren
[C#] XML Encoding eines XmlDocument ändern
[C#] XMLDocument in XDocument konvertieren
[C#] Rss Feed in XMLDocument laden
[VB.NET] XML Datei in DataSet einlesen
[C#] Image zu Base64 konvertieren und zurück
[C#] Konvertiert Code nach Example für XML-Kommentar
[C#] XMLIO - einfachstes (De)serialisieren von/zu XML-Dateien
[C#] Generisch XML De-/ Serialisieren
[C#] XML generieren mit Linq to XML
[C#] 3 arten der Serialisierung bzw Deserialisierung
[C#] Spracherkennung
[C#] Wunderground Wettervorhersage
[C#] ComboBox mit Inhalten aus Datenbank füllen
[C#] Backup und Restore einer SQL-Server-Datenbank über SMO
[VB.NET] Convert DataGridViewRow nach DataRow
[VB.NET] Convert DataGridViewRow nach Objekt-Typ
[C#] Daten aus einer Datenbank in WPF darstellen
[C#] ASP.NET AJAX - Daten aus ADO.NET Data Services nutzen
[C#] Prüfen, ob exklusiver Zugriff auf eine Access-DB möglich ist
[C#] SMO : Alle Datenbanken einer Serverinstanz abfragen
[C#] Listen effektiv in ein Datenbankfeld speichern
[C#] SimpleDb
[C#] Connection-String Dialog öffnen
[VB.NET] Erstellt aus einem Bytearray eine Temporäre Datei
[C#] Datenbank-abfrage
[VB.NET] Mini-Sql-Command-Generator
[C#] ADO.NET Data Services mit einer Oracle-Datenbank
[C#] Datenbank als Webdienst in .NET 4.0 veröffentlichen
[C#] Mit LINQ to SQL auf eine Datenbank zugreifen
[C#] WPF Tutorial: Auf Datenbankinhalte mit WCF zugreifen

schlecht sehr gut
1 2 3 4 5 6 7 8 9 10
Nur angemeldete User können Snippets bewerten.