Benutzer mit den meisten Antworten
Neuen User in zwei Tabellen anlegen

Frage
-
Hallo zusammen,
ich habe in einer MS-SQL-Datenbank zur Usererfassung zwei Tabellen angelegt.
Die erste Tabelle heißt 'Student' und hat den Primärschlüssel Student_id.
Die zweite Tabelle heißt 'Fachgebiet' und hat den Primärschlüssel Fach_id und den Fremdschlüssel Student_id.Das Anlegen von Datensätzen in die erste Tabelle(Student) funktioniert fehlerlos mit:
INSERT INTO dbo.Student (Vorname, Email, Passwort, RegDatum, Gender, Birthda) Values (" & werte & ")'werte' ist eine Variable in VB.net, die die einzelnen Spaltenwerte enthält.
Nun gibt es aber noch weitere Werte(LastVisit, Anzahl_der_Besuche, Note), die in die Tabelle 'Fachgebiete' eingetragen werden müssen.
Die Verbindung der beiden Tabellen wird ja über die Fremdschlüsselbeziehung 'Student_id' hergestellt.Nur, wie muss der SQL-Code aussehen, damit in die Tabelle 'Fachgebiet' ebenfalls der Datensatz reingeschrieben wird?
Vielen Dank für Eure Antworten!
Rheinschiffer_70
Antworten
-
Hallo!
Da Du explizit nach dem SQL-Code fragst, hier ein vereinfachtes Beispiel (weniger Spalten und ohne PK und FK):
Create table #Student (Student_id int identity, Vorname varchar(20), Email varchar(20)) ; Create table #Fachgebiete (Fach_id int identity, Student_id int, LastVisit date, Anzahl_der_Besuche int , Note decimal(3,2)) ; Insert into #Student(Vorname, Email) values ('Rheinschiffer', 'r@test.de'); Insert into #Fachgebiete(Student_id, LastVisit, Anzahl_der_Besuche, Note) Select Student_id, GETDATE() as LastVisit, 1 as Anzahl_der_Besuche, 1.0 as Note from #Student where Vorname = 'Rheinschiffer'; Select * from #Student; Select * from #Fachgebiete; go drop table #Student; drop table #Fachgebiete;
HTH!
Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Moderator Dienstag, 24. September 2019 07:23
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Moderator Mittwoch, 2. Oktober 2019 14:13
-
Hi,
anstelle der Verkettung mit "werte" sollten besser zur Verhinderung von Injection und weiteren Fehlern Parameter genutzt werden.Wenn es sich bei Student_id um einen Autowert handelt, kann dieser direkt nach dem Insert mit der gleichen SQL Anweisung zurück gelesen werden.
Hier mal eine Konsolendemo:
Imports System.Data.SqlClient Module Module1 Sub Main() Try With (New Demo) .CreateDataTables() .SaveData() .Test() End With Catch ex As Exception Console.WriteLine(ex.ToString) End Try Console.WriteLine("Continue enter key") Console.ReadKey() End Sub Friend Class Demo ''' <summary> ''' Delete old Student and Fachgebiet ''' Create New Student and Fachgebiet ''' </summary> Friend Sub CreateDataTables() Using cn As New SqlConnection(My.Settings.cnSQL) cn.Open() Using cmd As New SqlCommand("", cn) ' Delete old Tables, ignore error if table not exists cmd.CommandText = "DROP Table [Student]" Try cmd.ExecuteNonQuery() Catch ex As Exception End Try cmd.CommandText = "DROP Table [Fachgebiet]" Try cmd.ExecuteNonQuery() Catch ex As Exception End Try ' create new tables cmd.CommandText = "CREATE Table [Student]([Student_id] int Identity, [Name] nvarchar(50), CONSTRAINT [PK_Student] PRIMARY KEY ([Student_id]))" cmd.ExecuteNonQuery() cmd.CommandText = "CREATE Table [Fachgebiet]([Fach_id] int Identity, [Student_id] int, [Note] int, CONSTRAINT [PK_Fach] PRIMARY KEY ([Fach_id]))" cmd.ExecuteNonQuery() End Using End Using End Sub ''' <summary> ''' Load jpg and save inti Table1 ''' </summary> Friend Sub SaveData() Using cn As New SqlConnection(My.Settings.cnSQL) cn.Open() ' cmd1 für Master-Datensatz (Student) Using cmd1 As New SqlCommand("", cn) cmd1.CommandText = "INSERT INTO dbo.Student (Name) Values (@Name); SELECT Scope_Identity()" cmd1.Parameters.Add("@Name", SqlDbType.NVarChar) ' cmd2 für Child-Datensatz (Fachgebiet) Using cmd2 As New SqlCommand("INSERT INTO dbo.Fachgebiet (Student_id, Note) Values (@Student_id, @Note)", cn) cmd2.Parameters.Add("@Student_id", SqlDbType.Int) cmd2.Parameters.Add("@Note", SqlDbType.Int) ' Schleife für das Hinzufügen von mehreren Master-Datensätzen For i = 1 To 5 cmd1.Parameters("@Name").Value = $"Name {i}" Dim id = cmd1.ExecuteScalar ' dazu einen Child-Datensatz hinzufügen cmd2.Parameters("@Student_id").Value = id cmd2.Parameters("@Note").Value = i cmd2.ExecuteNonQuery() Next End Using End Using End Using End Sub ''' <summary> ''' Test, display inserted records ''' </summary> Friend Sub Test() Using cn As New SqlConnection(My.Settings.cnSQL) cn.Open() Using cmd As New SqlCommand("SELECT Student.Name, Fachgebiet.Note FROM dbo.Student INNER JOIN dbo.Fachgebiet ON Student.Student_id = Fachgebiet.Student_id", cn) Dim rdr = cmd.ExecuteReader While rdr.Read Console.WriteLine($"Name: {rdr(0)}, Note: {rdr(1)}") End While End Using End Using End Sub End Class End Module
--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks- Bearbeitet Peter Fleischer Donnerstag, 19. September 2019 03:37
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Moderator Dienstag, 24. September 2019 07:23
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Moderator Mittwoch, 2. Oktober 2019 14:13
Alle Antworten
-
In dem du dir die Student-ID per Select aus Student ausliest und dann beim Insert in Fachgebiet mit angibst.
Die Fremdbeziehung dient nur dem einfacheren Verbinden der Tabellen mit Join.
Die meisten Programmier-Frameworks benötigen ID-Fields als Primary Key. -
Hi,
anstelle der Verkettung mit "werte" sollten besser zur Verhinderung von Injection und weiteren Fehlern Parameter genutzt werden.Wenn es sich bei Student_id um einen Autowert handelt, kann dieser direkt nach dem Insert mit der gleichen SQL Anweisung zurück gelesen werden.
Hier mal eine Konsolendemo:
Imports System.Data.SqlClient Module Module1 Sub Main() Try With (New Demo) .CreateDataTables() .SaveData() .Test() End With Catch ex As Exception Console.WriteLine(ex.ToString) End Try Console.WriteLine("Continue enter key") Console.ReadKey() End Sub Friend Class Demo ''' <summary> ''' Delete old Student and Fachgebiet ''' Create New Student and Fachgebiet ''' </summary> Friend Sub CreateDataTables() Using cn As New SqlConnection(My.Settings.cnSQL) cn.Open() Using cmd As New SqlCommand("", cn) ' Delete old Tables, ignore error if table not exists cmd.CommandText = "DROP Table [Student]" Try cmd.ExecuteNonQuery() Catch ex As Exception End Try cmd.CommandText = "DROP Table [Fachgebiet]" Try cmd.ExecuteNonQuery() Catch ex As Exception End Try ' create new tables cmd.CommandText = "CREATE Table [Student]([Student_id] int Identity, [Name] nvarchar(50), CONSTRAINT [PK_Student] PRIMARY KEY ([Student_id]))" cmd.ExecuteNonQuery() cmd.CommandText = "CREATE Table [Fachgebiet]([Fach_id] int Identity, [Student_id] int, [Note] int, CONSTRAINT [PK_Fach] PRIMARY KEY ([Fach_id]))" cmd.ExecuteNonQuery() End Using End Using End Sub ''' <summary> ''' Load jpg and save inti Table1 ''' </summary> Friend Sub SaveData() Using cn As New SqlConnection(My.Settings.cnSQL) cn.Open() ' cmd1 für Master-Datensatz (Student) Using cmd1 As New SqlCommand("", cn) cmd1.CommandText = "INSERT INTO dbo.Student (Name) Values (@Name); SELECT Scope_Identity()" cmd1.Parameters.Add("@Name", SqlDbType.NVarChar) ' cmd2 für Child-Datensatz (Fachgebiet) Using cmd2 As New SqlCommand("INSERT INTO dbo.Fachgebiet (Student_id, Note) Values (@Student_id, @Note)", cn) cmd2.Parameters.Add("@Student_id", SqlDbType.Int) cmd2.Parameters.Add("@Note", SqlDbType.Int) ' Schleife für das Hinzufügen von mehreren Master-Datensätzen For i = 1 To 5 cmd1.Parameters("@Name").Value = $"Name {i}" Dim id = cmd1.ExecuteScalar ' dazu einen Child-Datensatz hinzufügen cmd2.Parameters("@Student_id").Value = id cmd2.Parameters("@Note").Value = i cmd2.ExecuteNonQuery() Next End Using End Using End Using End Sub ''' <summary> ''' Test, display inserted records ''' </summary> Friend Sub Test() Using cn As New SqlConnection(My.Settings.cnSQL) cn.Open() Using cmd As New SqlCommand("SELECT Student.Name, Fachgebiet.Note FROM dbo.Student INNER JOIN dbo.Fachgebiet ON Student.Student_id = Fachgebiet.Student_id", cn) Dim rdr = cmd.ExecuteReader While rdr.Read Console.WriteLine($"Name: {rdr(0)}, Note: {rdr(1)}") End While End Using End Using End Sub End Class End Module
--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks- Bearbeitet Peter Fleischer Donnerstag, 19. September 2019 03:37
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Moderator Dienstag, 24. September 2019 07:23
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Moderator Mittwoch, 2. Oktober 2019 14:13
-
Hallo!
Da Du explizit nach dem SQL-Code fragst, hier ein vereinfachtes Beispiel (weniger Spalten und ohne PK und FK):
Create table #Student (Student_id int identity, Vorname varchar(20), Email varchar(20)) ; Create table #Fachgebiete (Fach_id int identity, Student_id int, LastVisit date, Anzahl_der_Besuche int , Note decimal(3,2)) ; Insert into #Student(Vorname, Email) values ('Rheinschiffer', 'r@test.de'); Insert into #Fachgebiete(Student_id, LastVisit, Anzahl_der_Besuche, Note) Select Student_id, GETDATE() as LastVisit, 1 as Anzahl_der_Besuche, 1.0 as Note from #Student where Vorname = 'Rheinschiffer'; Select * from #Student; Select * from #Fachgebiete; go drop table #Student; drop table #Fachgebiete;
HTH!
Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Moderator Dienstag, 24. September 2019 07:23
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Moderator Mittwoch, 2. Oktober 2019 14:13
-
@@IDENTITY: liefert den letzten erzeugten Identity-Wert.
@@Identity bringt nur den richtigen Wert, wenn keine Trigger eingesetzt werden, die ggf. auch ein Insert mit Autowert in einer anderen Tabelle ausführen. Besser ist da Scope_Indentity().--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks -
Ich hatte bewusst auf die Ermittlung des IDENTITY-Wertes über Funktionen verzichtet, da ja der Student nur einmal angelegt wird, aber im Laufe seines Lebens mehrfach Noten bekommt.
Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu