Laden...

Problem mit MSSQL und C#...

Erstellt von King-Malkav vor 17 Jahren Letzter Beitrag vor 17 Jahren 7.567 Views
King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren
Problem mit MSSQL und C#...

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

X
2.051 Beiträge seit 2004
vor 17 Jahren

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

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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

X
2.051 Beiträge seit 2004
vor 17 Jahren

sorry hier war noch ein copy&past-fehler 🙂

... WHERE Nachname LIKE @Nachname"

also es muss ohne = zeichen sein.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

Danke jetzt funktioniert es...eigentlich ganz einfach, aber irgendwie bin ich wohl zu blöd für die Onlinehilfe...

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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 🙂

E
265 Beiträge seit 2004
vor 17 Jahren

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.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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);
			}

E
265 Beiträge seit 2004
vor 17 Jahren

Es gibt mehrere möglichkeiten. Ich verwende SELECT @@IDENTITY

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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

MFG

3.003 Beiträge seit 2006
vor 17 Jahren

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)

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

Danke, werde es mal testen. MFG

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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

E
265 Beiträge seit 2004
vor 17 Jahren

@@IDENTITY sollte funktionieren

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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?

E
265 Beiträge seit 2004
vor 17 Jahren

Zwischen @@IDENITY und @@IDENTITY ist ein kleiner aber feiner unterschied.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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...

E
265 Beiträge seit 2004
vor 17 Jahren

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?

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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.

E
265 Beiträge seit 2004
vor 17 Jahren

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" );
				}
			}
		}

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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.

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

E
265 Beiträge seit 2004
vor 17 Jahren
  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?

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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

E
265 Beiträge seit 2004
vor 17 Jahren

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 ^^

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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

MFG

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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

E
265 Beiträge seit 2004
vor 17 Jahren

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".

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

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

E
265 Beiträge seit 2004
vor 17 Jahren

.... 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?

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

Danke jetzt hab ichs verstanden...Jetzt Funzt es endlich!

Danke! für deine Hilfe.

Mal schauen wenn das nächste Problem auftaucht.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

Heute ist irgendwie nicht mein Tag!

Ich hab ein Problem (wer hätte das gedacht...), mal wieder. Ich hab ein Listbox, dass ich per Datasource und Display Member an ein Dataset binde. In dem Dataset sind nur bestimmte Daten die ich über eine SQL Abfrage auswähle. Soweit so gut.

Die Tabelle ist in Vorname, Nachname und ID unterteilt. In meiner Listbox hätte ich gern das Ergebnis der SQL Abfrage und zwar Nachname, Vorname. Gearbeitet wird wieder mit der ID.

Ich bekomme aber nur hin, dass ich entweder nur die Nachnamen oder die Vornamen angezeigt bekomme, aber nicht beides.

 
listBox1.DataSource = ds;
			listBox1.DisplayMember = "mitarbeiter.Vorname";
			listBox1.ValueMember = "mitarbeiter.ID";	

Gibt es eine einfache Möglichkeit mein vorhaben zu realisieren? Leider steht in meinen Büchern nix drin oder es wird mit dem Assistenten gelöst (aber auch nicht so wie ich es brauche).

MFG

E
265 Beiträge seit 2004
vor 17 Jahren

Nope, du kannst nur eine Spalte anzeigen.
Du kannst aber das SELECT ändern.

SELECT (Vorname + ' ' + Nachname) as VollerName ......

und dann diese spalte an die listbox binden.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

Danke, werds versuchen. Wollte nicht unbedingt mit nem DataGrid arbeiten, da es bei dem Listbox Object recht einfach ist, mit dem Ausgewählten Datensatz zu arbeiten.

MFG

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

Hab jetzt ein ganz anderes Problem, hat nicht unbeding direkt was mit sql zu tun. Ich will von zwei Windows Forms daten in die DB schreiben.
Ich hab in einem Form eine Hardware ID erzeugt und schreib sie in die Tabelle. In einem anderen Form suche ich mir ein USer aus mit einer UserID. Diese soll der Hardware ID zugeordnet werden. Wie kann ich das am geschicktesten machen?

Ich könnte z.B. eine globale Variable machen und da die Hardware ID reinschreiben die ich (weiter oben in dem Thread) mir vorher aus der DB ziehe und diese dann in dem anderen Form weiter nutze.

Oder gibt es einen besseren weg?

Hoffe es ist klar was ich machen will.

MFG

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

Hab mal wieder ein Problem. Und zwar hab ich folgenden Code:

 
// Zuordnung laden

			SqlDataAdapter dazuHardUser = new SqlDataAdapter("SELECT * FROM zuHardUser WHERE ID = @ID", sqlConnection1);
			dazuHardUser.SelectCommand.Parameters.Add("@ID", SqlDbType.Int,4).Value = zähler;
			DataSet dszuHardUser = new DataSet();
								
			try
			{				
				dszuHardUser.Clear();
				sqlConnection1.Open();
				dazuHardUser.Fill(dszuHardUser, "zuHardUser");
				sqlConnection1.Close();
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler " + ex.Message, "Fehler", MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
			
			
				DataTable dtzuHardUser = dszuHardUser.Tables["zuHardUser"];
				DataRow aRowzuHardUser = dtzuHardUser.Rows[0];
				string strzuHardUSer = aRowzuHardUser["zuID"].ToString();
				MessageBox.Show(strzuHardUSer);

Und zwar wähle ich eine Seriennummer über eine Combobox aus und benutze dessen ID um eine SQL Abfrage in der Tabelle zuHardUser (in der die USerID geschrieben steht) Das funktioniert, nur würde ich vorher gern überprüfen ob für die ID eine UserID hinterlegt ist. Da nicht jede Hardware mit einem User verknüpft ist.

Also ich habe 3 Tabellen:
Hardware
Aus der hol ich mir die Seriennummer und die Hardware ID

zuHardUser
in der Tabelle wird die Hardware ID und die UserID geschrieben (falls die Hardware einem Benutzer zugeordnet ist)

User
in der Tabelle stehen die Benutzerinformationen und die UserID.

Wie prüfe ich jetzt am besten ob für die Hinterlegte Hardware ID eine User ID existiert, denn ansonnsten bekomme ich eine Fehlermeldung.

MFG

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 17 Jahren

Mhh nochmal nach oben hol, hab immer noch keine Lösung gefunden während der Abfrage zu7 Prüfen ob daten vorhanden sind.

MFG