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 mit MSSQL und C#...
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

Problem mit MSSQL und C#...

beantworten | zitieren | melden

Hi ich hab folgendes Problem.

Ich hab eine SQL Tabelle mit Mitarbeitern, diese sollen in einem Datagrid ausgegeben werden, das Funktioniert auch so weit.
Allerdinsg möchte ich nur bestimmte Datensätze ausgeben. Dazu habe ich mir ein Textfeld gemacht wo man den Nachnamen angeben kann. Danach mache ich ein SQL Command und lade die daten in mein Dataset.
Wenn ich jetzt den ganzen Nachname angebe funktioniert das auch sehr gut, nur soll es auch funktionieren wenn ich nur den halben Namen angebe.
Leider bekomm ich das mit der Wildcard nicht auf die reihe.

Hier mal ein wenig Code

 
{
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM mitarbeiter WHERE Nachname = @Nachname", sqlConnection1);
			da.SelectCommand.Parameters.Add("@Nachname", SqlDbType.VarChar,30).Value = nachname.Text;
			DataSet ds = new DataSet();
			try
			{
				
				sqlConnection1.Open();
				da.Fill(ds, "mitarbeiter");
				da.Fill(dsmitarbeiter, "mitarbeiter");

				sqlConnection1.Close();
			
			
			
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}

			dataGrid1.SetDataBinding(ds, "mitarbeiter");
					
		}


Hoffe ihr könnt mir helfen.

MFG
private Nachricht | Beiträge des Benutzers
Xqgene
myCSharp.de - Member



Dabei seit:
Beiträge: 2.051

beantworten | zitieren | melden

versuch mal LIKE. viellecht nicht die beste lösung, aber sollte gehen


SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM mitarbeiter WHERE Nachname = LIKE @Nachname"


und Wildcard setzen

da.SelectCommand.Parameters.Add("@Nachname", SqlDbType.VarChar,30).Value = nachname.Text + '%';

also alle datensätze die mit Text im nachname beginnen
"A programmer is a tool which converts coffein to code."

Evely ToDo-Manager 1.2 (Build 1.2.585)
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Funktioniert leider nicht. Bekomme folgende Fehlermeldung:
In der Try Catch:
Fehler Falscher Syntax in der nähe des LIKE Schlüsselwortes

In VB:
Eine nicht behandelte Ausnahme des Typs 'System.ArgumentException' ist in system.windows.forms.dll aufgetreten.

Zusätzliche Informationen: Untergeordnete Liste für das Feld 'mitarbeiter' konnte nicht erstellt werden.

MFG
private Nachricht | Beiträge des Benutzers
Xqgene
myCSharp.de - Member



Dabei seit:
Beiträge: 2.051

beantworten | zitieren | melden

sorry hier war noch ein copy&past-fehler

... WHERE Nachname LIKE @Nachname"

also es muss ohne = zeichen sein.
"A programmer is a tool which converts coffein to code."

Evely ToDo-Manager 1.2 (Build 1.2.585)
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Danke jetzt funktioniert es...eigentlich ganz einfach, aber irgendwie bin ich wohl zu blöd für die Onlinehilfe...
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

So hab mal ein wenig rumgetestet.
Das soll es können bzw. kann es:
  • Suche über Seriennummer
  • Auflistung aller gefunden Geräte
  • Durch anklicken der Seriennummer und klick auf Daten Laden werden Zusatzinfos aus 2 Tabellen geladen


Hier mal mein Code, es besteht keine Beziehungen in der Datenbank und sollen auch nicht (wahrscheinlich, damit man einfach die Datenbank wechseln kann - Ich weiß es nicht).

 
private void button6_Click(object sender, System.EventArgs e)
		{
			// Ausgewählte Hardware ID in Variable zähler laden
				
			string zähler = listBox1.SelectedValue.ToString();
			
			// HardwareID laden und die dazugehörigen TypID und HerstellerID holen
			SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM hardware WHERE [Hardware ID] = @ID", sqlConnection1);
			da.SelectCommand.Parameters.Add("@ID", SqlDbType.Int,4).Value = zähler;
			DataSet ds = new DataSet();
								
			try
			{				
				ds.Clear();
				sqlConnection1.Open();
				da.Fill(ds, "hardware");
				sqlConnection1.Close();
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
			
			// Daten aus dem Dataset in die String Variablen laden
			DataTable dt = ds.Tables["hardware"];
			DataRow aRow = dt.Rows[0];
			string TypID = aRow["TypID"].ToString();
			string HerstellerID = aRow["HerstellerID"].ToString();
			
			// HerstellerID umwandeln in Hersteller Name
			
			SqlDataAdapter daHersteller = new SqlDataAdapter("SELECT Hersteller FROM hersteller WHERE ID = @HerstellerID", sqlConnection1);
			daHersteller.SelectCommand.Parameters.Add("@HerstellerID", SqlDbType.Int,4).Value = HerstellerID;
			DataSet dsHersteller = new DataSet();

			try
			{
				dsHersteller.Clear();
				sqlConnection1.Open();
				daHersteller.Fill(dsHersteller, "hersteller");
				sqlConnection1.Close();
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
			DataTable dtHersteller = dsHersteller.Tables["hersteller"];
			DataRow aRowHersteller = dtHersteller.Rows[0];
			string strhersteller = aRowHersteller["Hersteller"].ToString();

			// TypID umwandeln in HardwareTyp
			
			SqlDataAdapter daHardwareID = new SqlDataAdapter("SELECT hardWareTyp FROM hardtyp WHERE HWID = @TypID", sqlConnection1);
			daHardwareID.SelectCommand.Parameters.Add("@TypID", SqlDbType.Int,4).Value = TypID;
			DataSet dsHardwareID = new DataSet();

			try
			{
				dsHardwareID.Clear();
				sqlConnection1.Open();
				daHardwareID.Fill(dsHardwareID, "hardtyp");
				sqlConnection1.Close();
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
			DataTable dtHardwareID = dsHardwareID.Tables["hardtyp"];
			DataRow aRowHardwareID = dtHardwareID.Rows[0];
			string strtyp = aRowHardwareID["hardWareTyp"].ToString();
			
			// Füllen der Textfelder
			textBox3.Text = strhersteller;
			textBox4.Text = strtyp;

			
		
		}

Mir kommt es sehr aufwendig vor, hab ich viel Unnötiges Programmiert? Bin ja noch totaler anfänger *g*

Und zum Schluss, noch ein Bild wie das ganze aussieht

private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

Es funktioniert, was willst du mehr?

Mein vorschlag wäre das ganze ohne DatenAdapter zu machen.
Es wird eine Zeile on demand ausgelesen und nicht weiter verwendet. Hier ein DataSet zu verwenden ist IMHO overkill.

Es gibt jetzt mehrere Möglichkeiten wie man sowas anders/besser machen kann. Jedem wird was anderes einfallen ^^

Ein SELECT mit ein paar INNER JOIN wäre meine bevorzugte Variante. Das ergebnis in einen DataReader und den TextBoxen zuweisen. Vorrausetzung dafür ist, das jede SELECT das du geschrieben hast maximal eine Zeile zurück liefert. (schaut ganz danach aus)

Wenn dir INNER JOIN nix sagen oder du es so nicht machen willst.
Um den code zu kürzen könntest statt den DatenAdaptern, DataReader verwenden.


SqlDataReader reader;
SqlCommand cmd;
string TypID;
string HerstellerID;

string zähler = listBox1.SelectedValue.ToString();

sqlConnection1.Open();

cmd = new SqlCommand( "SELECT * FROM hardware WHERE [Hardware ID] = @ID", sqlConnection1 );
cmd.Parameters.Add( "@ID", SqlDbType.Int, 4 ).Value = zähler;

reader = cmd.ExecuteReader();
if( reader.Read() )
{
	TypID = (string)reader[ "TypID" ];
	HerstellerID = (string)reader[ "HerstellerID" ];
}
else
{			
	MessageBox.Show( "Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error );
	return;
}
reader.Close();

//... next slect ....
Sieht doch gleich lesbarer aus.
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Zitat
Original von EvilTK
Es funktioniert, was willst du mehr?

He He, stimmt. Aber es ist verdammt viel Tipparbeit. Da ich später von mehreren Tabellen lesen muss, wenn ich alles in Erinnerung habe, 7 Stück.

Das ganze soll eine "kleine" Inventur Anwendung werden.

Mein Problem:
Ich kann so gut wie kein SQL, hab noch nie mit .net gearbeitet, hab wenig bis keine Programmier Erfahrung (In der Ausbildung mal C++ gemacht).
Deshalb bin ich für jeden Tipp dankbar.
Zum Glück hab ich ein Konzept gezeichnet

Ich werde es nächste Woche mal ausstesten wenn ich wieder im Betrieb bin.
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Ach ja, die Probleme gehen weiter (wer hätte das Gedacht )

Ich schreibe einen Datensatz in meine Tabele. In der Datenbank wird ein Autowert generiert, dieser Nennt sich Hardware ID. Nun brauch ich allerdings die Hardware ID um die Daten weiter zu verarbeiten.

Gibt es eine Möglichkeit, dass ich nach dem Update die Hardware ID des gerade erzeugten Datensatz bekomme und dieser in eine string variable geschrieben wird?

 
{
			//Datenbank schreiben
			try
			{
				sqlConnection1.Open();
				DataRow objZeile;
				objZeile = dsHardware1.hardware.NewRow();
				objZeile["Seriennummer"] = Seriennummer.Text;
				objZeile["Bemerkungen"] = textBox1.Text;
				objZeile["TypID"] = comboBox3.SelectedValue.ToString();
				objZeile["HerstellerID"] = comboBox1.SelectedValue.ToString();
				dsHardware1.Tables["hardware"].Rows.Add(objZeile);
				sqlDAHardware.Update(dsHardware1, "hardware");
				sqlConnection1.Close();
				
				



			}

			catch (Exception ex)
			{
			MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

Es gibt mehrere möglichkeiten. Ich verwende SELECT @@IDENTITY
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Sorry wenn ich jetzt so blöd frag, wie genau funktionert deine lösung?

MFG
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3.003
Herkunft: Thüringen

beantworten | zitieren | melden

SELECT @@IDENITY liefert den Wert des zuletzt automatisch eingetragenen Schlüssels, dessen Spalte als IDENT gekennzeichnet ist. Einfach als SQL-Abfrage ausführen und das Ergebnis schnappen.

LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Danke, werde es mal testen. MFG
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Zitat
Original von LaTino
SELECT @@IDENITY liefert den Wert des zuletzt automatisch eingetragenen Schlüssels, dessen Spalte als IDENT gekennzeichnet ist. Einfach als SQL-Abfrage ausführen und das Ergebnis schnappen.

LaTino

Kann das sein, dass es nur bei Access Datenbanken funktioniert? Ich bekomme es bei meiner SQl Datenbank nicht hin - oder ich bin zu blöd.

MFG
private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

@@IDENTITY sollte funktionieren
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

So hab ichs gemacht:

 
SqlCommand idCMD = new SqlCommand("SELECT @@IDENITY", sqlConnection1); 
				if (args.StatementType == StatementType.Insert)
				{
					newID = (int)idCMD.ExecuteScalar();
					args.Row["Hardware ID"] = newID;
					sqlConnection1.Close();
				}				
				
				MessageBox.Show(newID);


so funktioniert es aber nicht, was mach ich falsch?
private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

Zwischen @@IDENITY und @@IDENTITY ist ein kleiner aber feiner unterschied.
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Mkay, danke sollte mal ein Kaffee einwerfen

Anderes Problem...er machts nämlich immernoch nicht.

 
private void button4_Click(object sender, System.EventArgs e)
		{
			
			
			//Datenbank schreiben
			try
			{
				sqlConnection1.Open();
				DataRow objZeile;
				objZeile = dsHardware1.hardware.NewRow();
				objZeile["Seriennummer"] = Seriennummer.Text;
				objZeile["Bemerkungen"] = textBox1.Text;
				objZeile["TypID"] = comboBox3.SelectedValue.ToString();
				objZeile["HerstellerID"] = comboBox1.SelectedValue.ToString();
				dsHardware1.Tables["hardware"].Rows.Add(objZeile);
							
				sqlDAHardware.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
				sqlDAHardware.Update(dsHardware1, "hardware");
			}
		
		

			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
		}
		
		private void  OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
		{
			int newID;	
			
			SqlCommand idCMD = new SqlCommand("SELECT @@IDENTITY", sqlConnection1); 
				
			if (args.StatementType == StatementType.Insert)
			{
				newID = (int)idCMD.ExecuteScalar();
				args.Row["Hardware ID"] = newID;
				sqlConnection1.Close();
			}
			
			SqlDataAdapter datest = new SqlDataAdapter("SELECT * FROM hardware WHERE ID = @HardwareID", sqlConnection1);
			datest.SelectCommand.Parameters.Add("@HardwareID", SqlDbType.Int,4).Value = newID;
			DataSet dstest = new DataSet();

			try
			{
				sqlConnection1.Open();
				datest.Fill(dstest, "hardware");
				sqlConnection1.Close();
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}	
			
			DataTable dttest = dstest.Tables["hardware"];
			DataRow aRowtest = dttest.Rows[0];
			string strtyp = aRowtest["Hardware ID"].ToString();
			textBox6.Text = strtyp;
		}

als Fehlermeldung bekomm ich
Verwendung von möglicherweise nicht zugewiesenen lokalen Variablen 'newID'

was mach ich falsch...
private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

Die Fehlermeldung ist basic ....
int newID = 0;

Weitere punkte.

Der sqlDAHardware DatenAdapter verwendet wahrscheinlich ebenfalls die sqlConnection1.
Während dem Updaten drehst du ihm einfach die Connection zu ....
SqlConnection1.Close() raus damit

Was machst du wenn das INSERT fehlgeschlagen hat?
z.z. machst du trozdem weiter.
If wie folgt erweitern


if (args.StatementType == StatementType.Insert &&
args.Status == UpdateStatus.Continue )

Und das SELECT nach dem zuweisen, verschwindet noch oder?
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Hi, stimmt, da ist mir wohl ein fehler unterlaufen *g* Bin noch nicht wirklich fit.
Hab jetzt alles Korrigiert, allerdings bekomm ich jetzt die Meldung "Die Angegebene Umwandlung ist ungültig". Das Programm bleibt weiter aktiv, allerdings schließt er nicht sie SQL Connection.

Hier mal mein abgeänderter Code. Die Messagebox ist zum testen und fliegt später wieder raus.

 
private void button4_Click(object sender, System.EventArgs e)
		{
			
			
			//Datenbank schreiben
			try
			{
				sqlConnection1.Open();
				sqlDAHardware.Fill(dsHardware1, "hardware");
				
				DataRow objZeile;
				objZeile = dsHardware1.hardware.NewRow();
				objZeile["Seriennummer"] = Seriennummer.Text;
				objZeile["Bemerkungen"] = textBox1.Text;
				objZeile["TypID"] = comboBox3.SelectedValue.ToString();
				objZeile["HerstellerID"] = comboBox1.SelectedValue.ToString();
				
				dsHardware1.Tables["hardware"].Rows.Add(objZeile);
				sqlDAHardware.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
				sqlDAHardware.Update(dsHardware1, "hardware");
				sqlConnection1.Close();
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
		}
		
		private void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
		{
			MessageBox.Show("Test");
			int ID = 0;
			SqlCommand idCMD = new SqlCommand("SELECT @@IDENTITY", sqlConnection1); 
					
			if (args.StatementType == StatementType.Insert && args.Status == UpdateStatus.Continue )
			{
				ID = (int)idCMD.ExecuteScalar();
				args.Row["Hardware ID"] = ID;
				sqlConnection1.Close();
			}
			SqlDataAdapter datest = new SqlDataAdapter("SELECT * FROM hardware WHERE ID = @HardwareID", sqlConnection1);
			datest.SelectCommand.Parameters.Add("@HardwareID", SqlDbType.Int,4).Value = ID;
			DataSet dstest = new DataSet();

			try
			{
				sqlConnection1.Open();
				datest.Fill(dstest, "hardware");
				sqlConnection1.Close();
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}	
			MessageBox.Show(ID.ToString());
			DataTable dttest = dstest.Tables["hardware"];
			DataRow aRowtest = dttest.Rows[0];
			string test = aRowtest["Hardware ID"].ToString();
			
			
		}


MFG und danke für die Hilfe bis jetzt.
private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

Die zeile wäre noch ganz praktisch.
Ich hab noch nicht verstanden wozu das SELECT (-> DataSet ect.) brauchst.
Ist nur fehleranfällig und macht nichts.

Debugg mal den Code durch (ist 1zu1 übernommen + ein paar verbesserungen) und schau dir an welche werte die objekte haben. (eigentlich nur id)


		private void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
		{                    
			if (args.StatementType == StatementType.Insert && args.Status == UpdateStatus.Continue )
			{
				SqlCommand idCMD = new SqlCommand("SELECT @@IDENTITY", sqlConnection1);
				object id = idCMD.ExecuteScalar();
				if( id != null )
				{
					System.Diagnostics.Debug.WriteLine( "ID: " + id.ToString() + " Type: " + id.GetType().ToString() );
					if( id is Int32 )
					{
						args.Row["Hardware ID"] = (int)id;
					}
				}
				else
				{
					System.Diagnostics.Debug.WriteLine( "id ist null" );
				}
			}
		}
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Zitat
Original von EvilTK
Die zeile wäre noch ganz praktisch.
Ich hab noch nicht verstanden wozu das SELECT (-> DataSet ect.) brauchst.
Ist nur fehleranfällig und macht nichts.

Weiß nicht genau was du meinst.
Zitat
Debugg mal den Code durch (ist 1zu1 übernommen + ein paar verbesserungen) und schau dir an welche werte die objekte haben. (eigentlich nur id)

Hab ich mal gemacht und hab das Ergebnis per MessageBox Ausgeben lassen. Funktioniert. Nur muss ich die "id" in eine andere Variable geben um damit zu arbeiten.


private void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
			{                    
				string id2 = " ";
				
				if (args.StatementType == StatementType.Insert && args.Status == UpdateStatus.Continue )
				{
					SqlCommand idCMD = new SqlCommand("SELECT @@IDENTITY", sqlConnection1);
					object id = idCMD.ExecuteScalar();
					id2 = id.ToString();
					if( id != null )
					{
						System.Diagnostics.Debug.WriteLine( "ID: " + id.ToString() + " Type: " + id.GetType().ToString() );
						if( id is Int32 )
						{
							args.Row["Hardware ID"] = (int)id;
						
						}
					}
					else
					{
						System.Diagnostics.Debug.WriteLine( "id ist null" );
					}
				}
				MessageBox.Show(id2);	
		}

Aber ehrlich gesagt verstehe ich deinen Code nicht, dass ist noch zu hoch für mich.
Bin ja noch absoluter anfänger. Kannst das mal kurz Erklären?
Was mir auffählt. Wenn ich meinetwegen 2 neue Hardwareobjekte erfasse, wird die Messagebox einmal bei der ersten Hardware dargestellt und bei der 2. Hardware 2 mal. Der Wert von id stimmt aber.
MFG
private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

1. update versuch - event abonnieren - 1 event wird geworfen
2. update versuch - noch ein event abonnieren - nun werden 2 geworfen
3. update versuch - .... rate mal ^^;;

Das RowUpdated event einmal nach dem konstruieren abonnieren.


Ja, was macht mein code.
Zuerst wird überprüft ob das Event durch ein "gültiges" "Insert" ausgelöst wurde.
Wenn das INSERT einen fehler verursacht hat brauchen wir gar nicht versuchen die ID auszulesen, das gleiche bei einem UPDATE. @@IDENTITY gibt uns keine ID zurück.
Der Code der die AutoIncrement ID betrifft, muss alles in dieser IF passieren (incl. deiner MessageBox).
Danach hole ich mir die letzte generierte ID von der Datenbank.
@@IDENTITY (bzw. ExecuteScalar) liefert mir null oder eine glütige id zurück. Ich bin auf nummer sicher gegangen und gesagt ich speichere das ganz in einer object variable (wegen null, int variablen können nicht null sein). Und überprüfe ob ich einen Wert habe.
Alles wichtige ausgeben lassen (noch nie in den output geguckt oder?)
Zur sicherheit nochmal überprüfen ob es sich um einen int handelt. Unnötig, keine ahnung wieso ich das extra überprüfe.
Zu guter letzt, weisen wir der Row die hinzugefügt wurde die AutoIncrementId zu.


Was willst du mit der ID noch machen?
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Ich brauche die ID um die gerade eingegebene Hardware einem Benutzer oder einem Arbeitsplatz zuzuordnen. Das ganze geschieht über eine Zuordnungstabelle.
Das einfachste währe ja das dirket in die Hardware Tabelle zu schreiben, dies ist aber nicht gewünscht.

das ganze läuft dann so:

Hardware ID 5 | Benuter ID 23
Hardware ID 5 | Software ID 669
.
.
.

Hoffe es ist klar wie es gemeint ist.

MFG
private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

Typed DataSets ... falls du lust und zeit hast kannst du dir das mal zu gemüte führen.

Kein Problem

2 Möglichkeiten in deinem Fall

Im RowUpdated Event


args.Row["Hardware ID"] = (int)id;
//Hier kommt spezialcode ^^

Oder nach dem Update();


DataRow objZeile;
objZeile = dsHardware1.hardware.NewRow();
objZeile["Seriennummer"] = Seriennummer.Text;
objZeile["Bemerkungen"] = textBox1.Text;
objZeile["TypID"] = comboBox3.SelectedValue.ToString();
objZeile["HerstellerID"] = comboBox1.SelectedValue.ToString();

dsHardware1.Tables["hardware"].Rows.Add(objZeile);
sqlDAHardware.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
sqlDAHardware.Update(dsHardware1, "hardware");
sqlConnection1.Close();
//Im DataAdapter.Update wurde das RowUpdated Event ausgelöst
//Der Row objZeile wurde dort eine gültige ID zugewiesen
//d.h. wir können hier die ID auslesen und damit machen was wir wollen
int id = (int)objZeile[ "Hardware ID" ];

Die 2. Variante würd ich bevorzugen ... ne wenn ich ehrlich bin würd ich TypedDataSets verwenden ^^
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Ok, werd mir das morgen mal anschauen, muss nämlich noch für meinen MCSA lernen. Danke für die Hilfe.

MFG
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Hi, wenn ich es nach der 2. Variante mache, dann bekomm ich nen falschen wert geliefert. Scheinbar erstellt das Dataset selbst einen Autowert ( Es sind 10 Zeilen drin und als Wert bekomme ich auch ID 10 ).

Hab das Dataset damals mit dem Assistenten erstellt.

In der Debugg konsole wird mir der richtige Wert ausgegeben (logisch, von dem OnRowUpdated Code, der ja funktioniert).

MFG
private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

o.O Unmöglich, behaupte ich mal.

Die Row existiert instanz mäßig nur einmal. d.h. wenn du im RowUpdated ne gültige ID in die Row schreibst, musst du diese außerhalb des events genauso haben.

.....

Jetzt hab ich es echt nachprogrammiert *seufz* Bei mir funktioniert es.

Du hast doch Visual Studio 2003 oder? DEBUGGEN!!!
2 Fehler
1. @@IDENTITY gibt einen decimal und keinen int zurück (zumindest bei mir ... liegt eventuell am SQL2005)
Ich überprüfe explicit ob der Datentyp ein int ist (hätt ich nicht machen sollen), da er das nicht ist, findet keine zuweisung statt du hast nachdem Update(); noch die alte ID.

2. e.Row[ "Hardware ID" ] ist mit großer wahrscheinlichkeit schreibgeschützt.
e.Row.Table.Columns[ "Hardware ID" ].ReadOnly = false;
args.Row["Hardware ID"] = (decimal)id;
e.Row.Table.Columns[ "Hardware ID" ].ReadOnly = true;
Sonst bekommst du eine Exception "Spalte Hardware ID ist schreibgeschützt".
private Nachricht | Beiträge des Benutzers
King-Malkav
myCSharp.de - Member

Avatar #avatar-2613.jpg


Dabei seit:
Beiträge: 264
Herkunft: Landau

Themenstarter:

beantworten | zitieren | melden

Danke für deine Bemühungen,

ja ich habe Visual Studio 2003 und die MSDB SP4.

Ich bekomme keine Fehlermeldung. Läuft alles durch.

 
private void button4_Click(object sender, System.EventArgs e)
		{
			
			
			//Datenbank schreiben
			try
			{
				sqlConnection1.Open();
				sqlDAHardware.Fill(dsHardware1, "hardware");
				
				DataRow objZeile;
				objZeile = dsHardware1.hardware.NewRow();
				objZeile["Seriennummer"] = Seriennummer.Text;
				objZeile["Bemerkungen"] = textBox1.Text;
				objZeile["TypID"] = comboBox3.SelectedValue.ToString();
				objZeile["HerstellerID"] = comboBox1.SelectedValue.ToString();
				
				dsHardware1.Tables["hardware"].Rows.Add(objZeile);
				sqlDAHardware.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
				sqlDAHardware.Update(dsHardware1, "hardware");
				sqlConnection1.Close();
				int id = (int)objZeile[ "Hardware ID" ]; 
				MessageBox.Show(id.ToString());
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
		}

			private void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
			{                    
				if (args.StatementType == StatementType.Insert && args.Status == UpdateStatus.Continue )
				{
					SqlCommand idCMD = new SqlCommand("SELECT @@IDENTITY", sqlConnection1);
					object id = idCMD.ExecuteScalar();
					if( id != null )
					{
						System.Diagnostics.Debug.WriteLine( "ID: " + id.ToString() + " Type: " + id.GetType().ToString() );
						if( id is Int32 )
						{
							args.Row["Hardware ID"] = (int)id;
						
						}
					}
					else
					{
						System.Diagnostics.Debug.WriteLine( "id ist null" );
					}
				}
			
		}

So habe ich das im Moment und ich bekomm in der Messagebox immer 10 angezeigt, egal wieviel Hardware ich erfasse.

das Zeigt mir das Debug Fenster

'DefaultDomain': 'c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll' geladen, keine Symbole geladen.
'WindowsApplication1': 'C:\Dokumente und Einstellungen\testuser\Eigene Dateien\Visual Studio Projects\Bestand\bin\Debug\WindowsApplication1.exe' geladen, Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll' geladen, keine Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\system\1.0.5000.0__b77a5c561934e089\system.dll' geladen, keine Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\system.data\1.0.5000.0__b77a5c561934e089\system.data.dll' geladen, keine Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\system.xml\1.0.5000.0__b77a5c561934e089\system.xml.dll' geladen, keine Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\system.drawing\1.0.5000.0__b03f5f7f11d50a3a\system.drawing.dll' geladen, keine Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\system.enterpriseservices\1.0.5000.0__b03f5f7f11d50a3a\system.enterpriseservices.dll' geladen, keine Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\system.enterpriseservices\1.0.5000.0__b03f5f7f11d50a3a\system.enterpriseservices.thunk.dll' geladen, keine Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\mscorlib.resources\1.0.5000.0_de_b77a5c561934e089\mscorlib.resources.dll' geladen, keine Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\system.windows.forms.resources\1.0.5000.0_de_b77a5c561934e089\system.windows.forms.resources.dll' geladen, keine Symbole geladen.
'WindowsApplication1.exe': 'c:\windows\assembly\gac\system.data.resources\1.0.5000.0_de_b77a5c561934e089\system.data.resources.dll' geladen, keine Symbole geladen.
ID: 51 Type: System.Decimal
ID: 52 Type: System.Decimal
ID: 52 Type: System.Decimal
ID: 53 Type: System.Decimal
ID: 53 Type: System.Decimal
ID: 53 Type: System.Decimal
Das Programm "[3096] WindowsApplication1.exe" wurde mit Code 0 (0x0) beendet.

MFG
private Nachricht | Beiträge des Benutzers
EvilTK
myCSharp.de - Member



Dabei seit:
Beiträge: 265

beantworten | zitieren | melden

.... ich weis das ich nicht gut bin im erklären. Aber der fehler ist doch offensichtlich -_-

ID: 51 Type: System.Decimal

if( id is Int32 )
{
args.Row["Hardware ID"] = (int)id;
}

Ist System.Decimal der gleiche Datentyp wie System.Int32? Nein, also wie soll er jemals in die if springen und die Row updaten?
private Nachricht | Beiträge des Benutzers