Zum Inhalt springen

Anfänger: Connector SQL Server


Einzelstueck

Empfohlene Beiträge

Guten Tag!

Ich habe morgen einen Probearbeitstag und wollte mich etwas vorbereiten!

Ungefähr so eine Aufgabenstellung werde ich haben :

1. Ers telle eine Datenbankanwendung auf Basis einer MS SQL Datenbank ( adventure works 2012 )

Anforderung : Verbindungsparameter ( also wohl benutzer/PW ) nicht im programmcode einbinden

-- Geht es eigentlich das ich es im System eine ODBC Verbindung anlege? Damit würde ich mir doch einen Connector sparen oder ? Dort würde ich ja Zugangsdaten hinterlegen ?

Wüsste sonst nicht wie ich dies realisiere ohne direkt im Code PW/Benutzer anzulegen ? Hat wer da Beispiel Codes in C# oder so :-)?

2. Die Anwendung soll eine Erfassungsmaske für die Anlegung von Artikeln haben

(( Hat hier wer vllt ein gutes Tutorial Video in C# ?? ))

3. Die Anwendung soll eine Artikel Umsatzstatistik je. Monat grafisch darstellen können, der zu betrachende Artikel & Zeitraum muss einstellbar sein.

Die Datenbank selber ist schon angelegt worden.

( bei 3. steh ich ganz auf dem Schlauch ich weiß nicht wie man sowas grafisch darstellen kann... :( )

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn wir von C# reden, würde ich dir Entity Framework zur Datenbankverbindung und WPF für die GUI vorschlagen. Ist für einen Tag (der heute wohl auch schon rum ist) aber wohl zu viel.

Auf die Schnelle kann man sich vllt. in Winforms und die Bordmittel von .NET (SqlConnection etc.) ausreichend einarbeiten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Die Sache mit den ODBC Verbindungen verlagert nur das Problem: Du musst das Programm wissen lassen, welche ODBC Verbindung

genutzt werden soll.

Wie mir scheint, soll das einfach nur nicht hardgecodet werden - also DB-Parameter dynamisch Abfragen und ggf. speichern.

Zum generellen Speichern von Einstellungen wie Datenbankverbindung kann man sehr einfach die "Settings" benutzen:

https://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=DE-DE&k=k%28ApplicationSettingsOverview%29;k%28TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0%29&rd=true

https://msdn.microsoft.com/en-us/library/aa730869%28v=vs.80%29.aspx

Bei den Windows Forms gibt es afaik ab .Net 4 eine einfaches Chart/Diagrammklasse:

https://msdn.microsoft.com/de-de/library/dd489237.aspx

Edit: Ahh.. Das "morgen" von gestern wäre heute :) Ich hoffe Du hattest Erfolg..

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hey danke für die Antworten!Ich bin grade an diesem Chart am schauen wie das genau funktioniert. Habe auch schon einiges geschafft aber komme beieinem Fehler grade nicht weiter

"

try

{

con.Open();

SqlDataReader reader = cmd2.ExecuteReader();

DataTable tabelle = new DataTable();

tabelle.Columns.Add("Menge");

tabelle.Columns.Add("Name");

while (reader.Read())

{

DataRow Reihe = new DataRow();

Reihe = tabelle.NewRow();

Reihe("Menge")= reader("Menge");

tabelle.Rows.Add(Reihe);

}"

er bemängelt die ganze zeit die zeile : Reihe("Menge")= reader("Menge");

...ist eine variabelwird aber als methode verwendet... ?

2.

bei DataRow Reihe = new DataRow();

meckert er bei new DataRow();

der zugriff auf "system.data.datarow.datarow(system.data.datarowbuilder) ist aufgrund der sicherheitsebene nicht möglich-

Bearbeitet von Einzelstueck
Link zu diesem Kommentar
Auf anderen Seiten teilen

er bemängelt die ganze zeit die zeile : Reihe("Menge")= reader("Menge");

...ist eine variabelwird aber als methode verwendet... ?

Auf eine DataRow greifst du per Indexer zu, also
Reihe["Menge"]

statt der runden Klammern. Sieh dazu das Beispiel unter DataRow. Das ist beim SqlDataReader übrigens genauso.

bei DataRow Reihe = new DataRow();

meckert er bei new DataRow();

der zugriff auf "system.data.datarow.datarow(system.data.datarowbuilder) ist aufgrund der sicherheitsebene nicht möglich-

Du kannst eine DataRow nicht aus dem Nichts erzeugen, sondern musst sie - so wie du es eine Zeile drunter ja auch schon machst - aus dem DataTable holen. Siehe DataTable.NewRow.

Und siehe auch DataRow - da steht unter Konstruktor:

Infrastruktur. Initialisiert eine neue Instanz der DataRow. Erstellt eine Zeile aus dem Generator. Nur zur internen Verwendung.

Ich empfehle jedem C#-Entwickler, die MSDN-Doku zu bemühen, wenn irgendwas unklar ist. In meinen Augen ist die echt gut gelungen und umfangreich.

Bearbeitet von arlegermi
Link zu diesem Kommentar
Auf anderen Seiten teilen

Der Konstruktor von DataRow ist aber nicht public - den darfst du "von außen" nicht aufrufen. Grund dafür ist, dass für eine DataRow noch weitere Aktionen nötig sind, damit du die benutzen kannst. Und dass die alle richtig ausgeführt werden, ist Aufgabe von DataTable.NewRow. Wenn du dir DataRow auf MSDN anguckst, siehst du, dass der Konstruktor eine geschützte Methode ist (das Schlüssel-Symbol da links).

Und du rufst ja auch DataTable.NewRow auf - wieso willst du denn danach noch eine neue Row erstellen?

Statt

DataRow Reihe = new DataRow();

Reihe = tabelle.NewRow();
brauchst du also nur
var Reihe = tabelle.NewRow();

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe mal kurz nachgeguckt, das hier ist der Code aus DataTable.NewRow:


public DataRow NewRow() {

    DataRow dr = NewRow(-1);

    NewRowCreated(dr); // this is the only API we want this event to be fired

    return dr;

}


internal DataRow NewRow(int record) {

    if (-1 == record) {

        record = NewRecord(-1);

    }


    rowBuilder._record = record;

    DataRow row = NewRowFromBuilder( rowBuilder );

    recordManager[record] = row;


    if (dataSet != null)

    DataSet.OnDataRowCreated( row );


    return row;

}


protected virtual DataRow NewRowFromBuilder(DataRowBuilder builder) {

    return new DataRow(builder);

}


// und in DataRow:

protected internal DataRow (DataRowBuilder builder) {

    tempRecord = builder._record;

    _table = builder._table;

    _columns = _table.Columns;

}

(Geholt aus referencesource.microsoft.com)

Wie du siehst, ist da ein bißchen was zu tun, damit du die DataRow richtig einsetzen kannst. Und um dem Entwickler das abzunehmen, ist das ganze Ding internal.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moment, lassen wir das manuelle zusammenfrickeln von Zeilen mal.

Du wolltest Daten vom SQL Server lesen und in eine DataTable packen, oder?

Da gibt's mehrere Wege:

a) Eine DataTable füllen und zur Anzeige/Bearbeitung im Speicher halten:

Dafür würde sich sich Verwendung von SqlDataAdapter eignen:


SqlDataAdapter dataAdapter = new SqlDataAdapter(selectCommand, connectionString);

DataTable table = new DataTable();

dataAdapter.Fill(table);

Und Du hast deine Daten fertig in der DataTable! Diese wird hierbei automatisch gefüllt, Spaltennamen und Datentypen kommen vom SQL Server. B) Eine Resultset zeilenweise verarbeiten (und immer nur eine Zeile im Speicher halten) - nur dann würde ich den SqlDataReader nutzen:

SqlDataReader reader;

using (reader = command.ExecuteReader())

    if (reader.HasRows)

    {

       while (reader.Read()) // while über alle Result-Zeilen

       {

                 string Name reader.GetString(reader.GetOrdinal("Name");

                 string Menge reader.GetInt32(reader.GetOrdinal("Menge");


        //     ...daraus eine DataRow erzeugen und mittels table.Rows.Add(DataRow) manuell in 

       //      die DataTable prügeln, etc.

       //      Kein sinniges Beispiel.. 


       }

    }

[/code]

Wie man sieht hat man bei Weg B) einiges mehr zu erledigen.

Die Unterschiede nochmal erklärt: https://msdn.microsoft.com/en-us/library/ms254931%28v=vs.110%29.aspx

Btw: Try..catch..finally hab ich weggelassen, sollte man aber zwecks Fehlerbehandlung immer dabei haben.

Wenn Du die Daten nachher sowie im Speicher hast (e.g. für nen Diagramm oder als DataGrid, etc.) würde ich immer zu Ansatz a) greifen.

Methode B) ist meist nur sinnvoll, wenn man eben jede Zeile einzeln bearbeiten möchte - z.B. wenn man einige GB an Daten exportiert und man das als eigenen Thread mit Fortschrittsanzeige laufen lassen will. Mit Methode a) würde dataAdapter.Fill(..) zum einen alles komplett in den Speicher lesen und das noch blockierend :)

Hth..

Ripper

Bearbeitet von RipperFox
Link zu diesem Kommentar
Auf anderen Seiten teilen

Arlegermi vielen dankfür deine Hilfe, also ich komme echt gut voran,morgen muss ich vorstellen heute ist mein letzter Tag,von allen Aufgaben sitze ich grade an der letzten... aber hier komme ich nicht weiter glaube ich habe irgendwo einen Logik Fehler.

Ziel ist es über eine Combobox ein Produkt zu wählen ( Habe ich fertig ), und dieses in einen Chart bzw. den Umsatz dieses Produktes auszugeben. Man Wählt in meiner Maske aus 2 Datepickern das Datum. Bzw. den Zeitraum VON -BIS.

Und dann soll Chart anzeigen Den Umsatz .

Das sieht für euch sicher sehr "wüst" aus, aber ich bin Anfänger was das anbelangt :/.

produktCombo();

chart1.Series.Add("Umsatz");

chart1.ChartAreas[0].AxisX.Maximum = 12;

chart1.ChartAreas[0].AxisX.Maximum = 0;

chart1.ChartAreas[0].AxisY.Minimum = 0;

chart1.ChartAreas[0].AxisY.Maximum = 12;

SqlCommand cmd2 = con.CreateCommand();

cmd2.CommandText = String.Format("SELECT SUM(Sales.SalesOrderDetail.LineTotal) AS Umsatz, Production.Product.Name, MONTH(Sales.SalesOrderHeader.OrderDate) AS Monat, YEAR(Sales.SalesOrderHeader.OrderDate) AS Jahr,Production.Product.ProductID "+

"FROM Production.Product INNER JOIN "+

"Sales.SalesOrderDetail ON Production.Product.ProductID = Sales.SalesOrderDetail.ProductID INNER JOIN "+

"Sales.SalesOrderHeader ON Sales.SalesOrderDetail.SalesOrderID = Sales.SalesOrderHeader.SalesOrderID "+

"GROUP BY Production.Product.Name, MONTH(Sales.SalesOrderHeader.OrderDate), YEAR(Sales.SalesOrderHeader.OrderDate), Production.Product.ProductID "+

"HAVING MONTH(Sales.SalesOrderHeader.OrderDate) >= 1) AND (YEAR(Sales.SalesOrderHeader.OrderDate) >= 2007) AND (MONTH(Sales.SalesOrderHeader.OrderDate) <= 12) AND "+

" (YEAR(Sales.SalesOrderHeader.OrderDate) <= 2009) "+

"ORDER BY Production.Product.Name, Monat, Jahr ");

/*

try

{

int Jahre = dtpBisDatum.Value.Year - dtpVonDatum.Value.Year;

for (int i=0; i>=Jahre;i++)

{

chart1.Series.Add(i.ToString());

}

con.Open();

SqlDataReader reader = cmd2.ExecuteReader();

while(reader.Read())

{

int intSeries = Convert.ToInt32(reader["Jahr"]);

chart1.Series[intSeries].Points.AddXY(reader["Monat"],reader["Umsatz"]);

}

}

catch (SqlException ex2)

{

MessageBox.Show(ex2.Message);

}

finally

{

con.Close();

}

post-96254-14430450076772_thumb.jpg

Bearbeitet von Einzelstueck
Link zu diesem Kommentar
Auf anderen Seiten teilen

@RipperFox

Also meinst du das so ?

SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd2, con);

DataTable tabelle = new DataTable();

dataAdapter.Fill(tabelle);

-Ist das selbe wie-

while (reader.Read())

{

var Reihe = tabelle.NewRow();

Reihe["Menge"] = reader["Menge"];

Reihe["Name"] = reader["Name"];

tabelle.Rows.Add(Reihe);

}

Bearbeitet von Einzelstueck
Link zu diesem Kommentar
Auf anderen Seiten teilen

Einzelstück:

Ein SqlDataAdapter ist auf einer höheren Abstraktionsstufe und kann noch mehr, als nur eine DataTable zu füllen - z.b. in die Datenbank zurückschreiben, etc.

Spart also ne Menge Tipparbeit.

Siehe z.B. c# - SqlDataAdapter vs SqlDataReader - Stack Overflow

Gewöhn Dich am besten von Anfang an daran, Parameter bei Abfragen zu nutzen:

AdoDotNet Lesson 06

Und: Strings wie die Query kann man dank "@" davor mit Newlines,etc. so schreiben:


command.CommandText = @"SELECT foo 

                                                   FROM bar

                                                   INNER JOIN bla on bla.id = foo.blaid

                                                   WHERE bar.Name = @Name";

command.Parameters.AddWithValue("@Name", _name);


Siehe: https://msdn.microsoft.com/en-us/library/aa691090%28v=vs.71%29.aspx

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...