Permalänk

SQL Server C#

Tjena Clockers! Allt bra hoppas jag
Sitter och försöker nöta lite sql commandon, har skapat en databas med ett table, gjorde endast ett table för att få rätt på det nu i början.
Tabellen ser ut såhär:

person_id (PK, int) person_firstName(nvarchar) person_lastName(nvarchar) person_gender(nvarchar) person_birth(date)

Sedan har jag skapat ett konsolprogram där en användare får lägga till en person.
Har ett menyval där jag vill att man skall kunna söka på en person i databasen genom att ange person_id.
Har nästan rivit av mig håret pga frustration.

sqlConnection.Open(); Console.Write("Search for a person by his or her's ID: "); int id = int.Parse(Console.ReadLine()); SqlCommand cmd = new SqlCommand("SELECT * FROM Person WHERE @id = person_id", sqlConnection); using (SqlDataReader reader = cmd.ExecuteReader()) { if (reader.HasRows) { while (reader.Read()) { if (reader.Equals(id)) { Console.Clear(); Console.WriteLine($"Person with ID {reader.GetInt32(0)} found!\n"); } } Console.Write("Press any key to return to the menu. . ."); Console.ReadKey(); } else { Console.Clear(); Console.WriteLine("No person was found, did you enter correct value?\n"); Console.Write("Press any key to return to the menu. . ."); Console.ReadKey(); } sqlConnection.Close(); }

Mitt sqlCommand med @id = person_id blev ett sista försök som jag inte ens själv trodde på..
Behöver jag skapa en vettig stored procedure här? Eller en function? Blir fan galen haha xD Snälla guidea mig på rätt väg..

Permalänk
Medlem
Skrivet av PapaDiouf:

Tjena Clockers! Allt bra hoppas jag
Sitter och försöker nöta lite sql commandon, har skapat en databas med ett table, gjorde endast ett table för att få rätt på det nu i början.
Tabellen ser ut såhär:

person_id (PK, int) person_firstName(nvarchar) person_lastName(nvarchar) person_gender(nvarchar) person_birth(date)

Sedan har jag skapat ett konsolprogram där en användare får lägga till en person.
Har ett menyval där jag vill att man skall kunna söka på en person i databasen genom att ange person_id.
Har nästan rivit av mig håret pga frustration.

sqlConnection.Open(); Console.Write("Search for a person by his or her's ID: "); int id = int.Parse(Console.ReadLine()); SqlCommand cmd = new SqlCommand("SELECT * FROM Person WHERE @id = person_id", sqlConnection); using (SqlDataReader reader = cmd.ExecuteReader()) { if (reader.HasRows) { while (reader.Read()) { if (reader.Equals(id)) { Console.Clear(); Console.WriteLine($"Person with ID {reader.GetInt32(0)} found!\n"); } } Console.Write("Press any key to return to the menu. . ."); Console.ReadKey(); } else { Console.Clear(); Console.WriteLine("No person was found, did you enter correct value?\n"); Console.Write("Press any key to return to the menu. . ."); Console.ReadKey(); } sqlConnection.Close(); }

Mitt sqlCommand med @id = person_id blev ett sista försök som jag inte ens själv trodde på..
Behöver jag skapa en vettig stored procedure här? Eller en function? Blir fan galen haha xD Snälla guidea mig på rätt väg..

Du måste mappa parameternamnet i frågan till ett faktiskt värde det ska få.
Släng in ett cmd.Parameters.AddWithValue("@id", id); eller något åt det hållet innan du kör frågan. (Skrivet på frihand i forumet, så är inte direkt supertestat, men principen är rätt)

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Skrivet av evil penguin:

Du måste mappa parameternamnet i frågan till ett faktiskt värde det ska få.
Släng in ett cmd.Parameters.AddWithValue("@id", id); eller något åt det hållet innan du kör frågan. (Skrivet på frihand i forumet, så är inte direkt supertestat, men principen är rätt)

Tack för info! Har försökt mig på detta nu, sp:

CREATE PROCEDURE [dbo].[spAddPerson] ( @person_firstname nvarchar(30), @person_lastname nvarchar(30), @person_gender nvarchar(30), @person_birth date, @person_id INT OUT ) AS BEGIN INSERT INTO Person VALUES(@person_firstname, @person_lastname, @person_gender, @person_birth) SELECT @person_id = SCOPE_IDENTITY() END

Tillsammans med min andra kod i VS:

Person addPerson = new Person(); string connString = ConfigurationManager.ConnectionStrings["connectToDataBase"].ConnectionString; string storedProcedure = "spAddPerson"; using(SqlConnection dbConn = new SqlConnection(connString)) { SqlCommand cmd = new SqlCommand(storedProcedure, dbConn); cmd.CommandType = CommandType.StoredProcedure; addPerson.FirstName = UserInputHandler.FirstName(); addPerson.LastName = UserInputHandler.LastName(); addPerson.Gender = UserInputHandler.Gender(); addPerson.Birth = UserInputHandler.Birth(); cmd.Parameters.AddWithValue("@person_firstname", addPerson.FirstName); cmd.Parameters.AddWithValue("@person_lastname", addPerson.LastName); cmd.Parameters.AddWithValue("@person_gender", addPerson.Gender); cmd.Parameters.AddWithValue("@person_birth", addPerson.Birth); SqlParameter outputParam = new SqlParameter(); outputParam.ParameterName = "@person_id"; outputParam.SqlDbType = SqlDbType.Int; outputParam.Direction = ParameterDirection.Output; cmd.Parameters.Add(outputParam); try { dbConn.Open(); cmd.ExecuteNonQuery(); PrintText.PrintSuccessfullyAdded(); } catch { PrintText.PrintSomethingWentWrong(); } finally { dbConn.Close(); }

Vet inte riktigt vad jag gör fel. När jag kompilerar detta så går den direkt till min catch efter jag fyllt i en persons uppgifter. Har du något tips?

Permalänk
Medlem
Skrivet av PapaDiouf:

Tack för info! Har försökt mig på detta nu, sp:

CREATE PROCEDURE [dbo].[spAddPerson] ( @person_firstname nvarchar(30), @person_lastname nvarchar(30), @person_gender nvarchar(30), @person_birth date, @person_id INT OUT ) AS BEGIN INSERT INTO Person VALUES(@person_firstname, @person_lastname, @person_gender, @person_birth) SELECT @person_id = SCOPE_IDENTITY() END

Tillsammans med min andra kod i VS:

Person addPerson = new Person(); string connString = ConfigurationManager.ConnectionStrings["connectToDataBase"].ConnectionString; string storedProcedure = "spAddPerson"; using(SqlConnection dbConn = new SqlConnection(connString)) { SqlCommand cmd = new SqlCommand(storedProcedure, dbConn); cmd.CommandType = CommandType.StoredProcedure; addPerson.FirstName = UserInputHandler.FirstName(); addPerson.LastName = UserInputHandler.LastName(); addPerson.Gender = UserInputHandler.Gender(); addPerson.Birth = UserInputHandler.Birth(); cmd.Parameters.AddWithValue("@person_firstname", addPerson.FirstName); cmd.Parameters.AddWithValue("@person_lastname", addPerson.LastName); cmd.Parameters.AddWithValue("@person_gender", addPerson.Gender); cmd.Parameters.AddWithValue("@person_birth", addPerson.Birth); SqlParameter outputParam = new SqlParameter(); outputParam.ParameterName = "@person_id"; outputParam.SqlDbType = SqlDbType.Int; outputParam.Direction = ParameterDirection.Output; cmd.Parameters.Add(outputParam); try { dbConn.Open(); cmd.ExecuteNonQuery(); PrintText.PrintSuccessfullyAdded(); } catch { PrintText.PrintSomethingWentWrong(); } finally { dbConn.Close(); }

Vet inte riktigt vad jag gör fel. När jag kompilerar detta så går den direkt till min catch efter jag fyllt i en persons uppgifter. Har du något tips?

Har inte försökt gå igenom koden för att se vad som är fel, men grundtipset skulle väl vara att läsa meddelandet i exception, kan nog tänkas vara till hjälp för att hitta felet/felen.

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Skrivet av evil penguin:

Har inte försökt gå igenom koden för att se vad som är fel, men grundtipset skulle väl vara att läsa meddelandet i exception, kan nog tänkas vara till hjälp för att hitta felet/felen.

Hmm, nånting med att birth inte är kompatibelt med int, har ju satt den som en int men det går ju såklart inte. ska kika på det!

Permalänk
Skrivet av evil penguin:

Har inte försökt gå igenom koden för att se vad som är fel, men grundtipset skulle väl vara att läsa meddelandet i exception, kan nog tänkas vara till hjälp för att hitta felet/felen.

Nu jäklar satt den, bra du tipsa om att läsa exception det glömde jag. Nu går det att lägga till personer via min stored procedure!

Permalänk

Nu försöker jag skapa en funktion där användaren ska få söka på ett person ID och få fram all information om denna personen.

CREATE PROCEDURE [dbo].[spSearchForPerson] ( @PersonID INT ) AS BEGIN SELECT * FROM Person WHERE @PersonID = Person.person_id END

Skall c# koden vara lik den för att lägga till en person eller bör jag tänka annorlunda? Alternativt, vad kan jag googla efter för att se mer kring detta

Permalänk
Medlem

Vilken approach har du tillämpat? Känns som att du gör det lite mer komplicerat än nödvändigt.

Visa signatur

AMD Ryzen 7 5800X3D | EVGA GeForce RTX 3080 10GB FTW3 ULTRA | ASUS ROG Strix B450-F Gaming | Corsair RM750X V2 | Crucial Ballistix Sport LT 3200MHz 16GB | Samsung 980 Pro 1TB | Crucial MX500 2TB | NZXT H500

Permalänk
Skrivet av Cenorida:

Vilken approach har du tillämpat? Känns som att du gör det lite mer komplicerat än nödvändigt.

Vad menar du med approach?
Har skapat en databas i SSMS samt ett simpelt table, person_id som primary key, förnamn, efternamn, kön och födelsedatum.
Efter det skapade jag ett konsolprogram, har en meny där användaren kan lägga till en person , ta bort en person, söka efter en person, visa alla personer.
All data skall skrivas till databasen, likt StreamWriter eller så. Det har jag fått till när man lägger till en person.
Där jag sitter fast nu är att jag vill kunna söka efter en person via dennes ID, exempelvis 1. Då vill jag skriva ut informationen om denna person i konsolen. Alltså att man kan söka efter en redan existerande person och få fram info kring denne. Det du ser ovan är mitt försök till en stored procedure som jag vill använda i visual studio för att få fram infon.
Hoppas du förstod förklaringen känner själv att den kanske är lite smått oklar, men fråga gärna annars. Vi har tenta om cirka 1-2 veckor så sitter och försöker nöta detta, så har du lite tips så tas dom gärna emot

Permalänk
Skrivet av PapaDiouf:

Nu försöker jag skapa en funktion där användaren ska få söka på ett person ID och få fram all information om denna personen.

CREATE PROCEDURE [dbo].[spSearchForPerson] ( @PersonID INT ) AS BEGIN SELECT * FROM Person WHERE @PersonID = Person.person_id END

Skall c# koden vara lik den för att lägga till en person eller bör jag tänka annorlunda? Alternativt, vad kan jag googla efter för att se mer kring detta

Några länkar
https://docs.microsoft.com/en-us/visualstudio/data-tools/crea...
https://www.codeproject.com/Articles/8477/Using-ADO-NET-for-B...

Eller så kan du söka direkt på GitHub (du behöver logga in för att söka inom alla githubs projects)
Om du söker på t.ex. new SqlCommand så får du 364,549 träffar om man filtrerar på C#.

Men, idag använder de flesta inte ADO.NET direkt utan går via Entity Framework, Dapper osv.
https://docs.microsoft.com/en-us/ef/core/
https://github.com/StackExchange/Dapper

Så några exempel i en annan tråd där samma sak görs i ADO.NET, Dapper och Entity Framework.
#18808191

https://github.com/search?q=new+SqlCommand&type=code

Permalänk
Medlem
Skrivet av zoomster2:

Några länkar
https://docs.microsoft.com/en-us/visualstudio/data-tools/crea...
https://www.codeproject.com/Articles/8477/Using-ADO-NET-for-B...

Eller så kan du söka direkt på GitHub (du behöver logga in för att söka inom alla githubs projects)
Om du söker på t.ex. new SqlCommand så får du 364,549 träffar om man filtrerar på C#.

Men, idag använder de flesta inte ADO.NET direkt utan går via Entity Framework, Dapper osv.
https://docs.microsoft.com/en-us/ef/core/
https://github.com/StackExchange/Dapper

Så några exempel i en annan tråd där samma sak görs i ADO.NET, Dapper och Entity Framework.
#18808191

https://github.com/search?q=new+SqlCommand&type=code

Är ändå inte fel att förstå grunderna innan man börjar lägga på abstraktionslager.
Annars blir man snart den utvecklaren som klagar på att EF är långsamt för man har noll insikt i hur SQL fungerar.

Permalänk
Medlem
Skrivet av zaibuf:

Är ändå inte fel att förstå grunderna innan man börjar lägga på abstraktionslager.
Annars blir man snart den utvecklaren som klagar på att EF är långsamt för man har noll insikt i hur SQL fungerar.

Haha, snacka om det. När du felsöker kod som maxar antalet parametrar du kan skicka med en query i nhibernate blir man snabbt varse om hur mycket saker och ting göms.

Where in list på fluent nhibernate alltså

Permalänk
Medlem
Skrivet av PapaDiouf:

Vad menar du med approach?
Har skapat en databas i SSMS samt ett simpelt table, person_id som primary key, förnamn, efternamn, kön och födelsedatum.
Efter det skapade jag ett konsolprogram, har en meny där användaren kan lägga till en person , ta bort en person, söka efter en person, visa alla personer.
All data skall skrivas till databasen, likt StreamWriter eller så. Det har jag fått till när man lägger till en person.
Där jag sitter fast nu är att jag vill kunna söka efter en person via dennes ID, exempelvis 1. Då vill jag skriva ut informationen om denna person i konsolen. Alltså att man kan söka efter en redan existerande person och få fram info kring denne. Det du ser ovan är mitt försök till en stored procedure som jag vill använda i visual studio för att få fram infon.
Hoppas du förstod förklaringen känner själv att den kanske är lite smått oklar, men fråga gärna annars. Vi har tenta om cirka 1-2 veckor så sitter och försöker nöta detta, så har du lite tips så tas dom gärna emot

I så fall har du tillämpat Database-First. Använder du Entity Framework för att länka samman din kod med databasen?

Det enklaste som du kan göra är att skapa en klass i koden med attribut som motsvarar de attribut som du använder i din databas-tabell. (Det finns mjukvara som gör detta automatisk) Därefter använder du klassen som datatyp för att deklarera en lista (List) i minnet, därefter tilldelar de värden som finns i databasen till listan och därefter använder listan för att create, read, update, and delete (CRUD).

Visa signatur

AMD Ryzen 7 5800X3D | EVGA GeForce RTX 3080 10GB FTW3 ULTRA | ASUS ROG Strix B450-F Gaming | Corsair RM750X V2 | Crucial Ballistix Sport LT 3200MHz 16GB | Samsung 980 Pro 1TB | Crucial MX500 2TB | NZXT H500

Permalänk
Skrivet av zaibuf:

Är ändå inte fel att förstå grunderna innan man börjar lägga på abstraktionslager.
Annars blir man snart den utvecklaren som klagar på att EF är långsamt för man har noll insikt i hur SQL fungerar.

Försöker att förstå, vi har gått igenom Sql denna kursen, men vi tittar på väldigt lite exemplen utan går mest på just grunderna och framförallt i teorin utan att testa det i kodväg så att säga. Jag tycker mig förstå saker bättre när jag ser hur man kan använda dem i praktiken. Därför försöker jag hitta lite svar på hur jag ska skriva kodmässigt eller åtminstone vad jag ska googla på då mina googlingar är urusla x'D, "how to search for id in sql server c#"...

Permalänk
Skrivet av zoomster2:

Några länkar
https://docs.microsoft.com/en-us/visualstudio/data-tools/crea...
https://www.codeproject.com/Articles/8477/Using-ADO-NET-for-B...

Eller så kan du söka direkt på GitHub (du behöver logga in för att söka inom alla githubs projects)
Om du söker på t.ex. new SqlCommand så får du 364,549 träffar om man filtrerar på C#.

Men, idag använder de flesta inte ADO.NET direkt utan går via Entity Framework, Dapper osv.
https://docs.microsoft.com/en-us/ef/core/
https://github.com/StackExchange/Dapper

Så några exempel i en annan tråd där samma sak görs i ADO.NET, Dapper och Entity Framework.
#18808191

https://github.com/search?q=new+SqlCommand&type=code

Grymt, första länken verkar vara lite det jag söker så ska fortsätta kolla där. Skapade även ett github konto nu när jag ändå håller på så ska kika runt lite där med.

Permalänk

Har skrivit detta just nu, får inget felmeddelande, utan den går direkt till min else och säger att inga rows hittades.

string storedProcedure = "spSearchForPerson"; using (SqlConnection dbConn = new SqlConnection(connString)) { SqlCommand cmd = new SqlCommand(storedProcedure, dbConn); cmd.CommandType = CommandType.StoredProcedure; int personID = UserInputHandler.PersonID(); SqlParameter outputParam = new SqlParameter(); outputParam.ParameterName = "@person_id"; outputParam.SqlDbType = SqlDbType.Int; outputParam.Direction = ParameterDirection.Output; cmd.Parameters.Add(outputParam); try { dbConn.Open(); using (SqlDataReader reader = cmd.ExecuteReader()) { if (reader.HasRows) { while (reader.Read()) { Console.WriteLine( $"{reader.GetValue(0)}, " + $"{reader.GetValue(1)}, " + $"{reader.GetValue(2)}, " + $"{reader.GetValue(3)}, " + $"{reader.GetDateTime(4)}" ); } PrintText.PrintReturnToMenu(); } else { PrintText.PrintNoRowsWereFound(); } } } catch(Exception msg) { Console.Clear(); Console.WriteLine(msg); Console.ReadKey(); } finally { dbConn.Close(); } }

Vart ligger felet? zzZZZz

Permalänk
Medlem

Utan att provköra eller liknande så vill jag nog påstå att du har ett problem med hur du specar parametern till din stored procedure. Det är en input-parameter och inte en output-parameter.

Gissningsvis skickar du just nu alltid in null i SP:n, eller i alla fall ett värde som gör att du inte får träff på något data, oavsett vad användaren matat in.

SSMS har en funktion för att titta på alla SQL-kommandon som körs i databasen. Så där kan du sniffa hur kommandot som körs ser ut när det kommit ner till databasen. SQL Server Profiler.

Ett annat tips är att aldrig använda SELECT *, speca i stället exakt vilka kolumner du vill ha tillbaka till applikationen, så vet du vilka/hur många kolumner som kommer tillbaka, att de kolumnerna inte har ändrat namn, och i vilken ordning kolumnerna kommer. Om det är en stor tabell och du vill ha alla kolumner så genererar SSMS lätt den frågan åt dig, högerklicka på tabellen och välj "Select from" eller liknande.

Permalänk
Skrivet av KAD:

Utan att provköra eller liknande så vill jag nog påstå att du har ett problem med hur du specar parametern till din stored procedure. Det är en input-parameter och inte en output-parameter.

Gissningsvis skickar du just nu alltid in null i SP:n, eller i alla fall ett värde som gör att du inte får träff på något data, oavsett vad användaren matat in.

SSMS har en funktion för att titta på alla SQL-kommandon som körs i databasen. Så där kan du sniffa hur kommandot som körs ser ut när det kommit ner till databasen. SQL Server Profiler.

Ett annat tips är att aldrig använda SELECT *, speca i stället exakt vilka kolumner du vill ha tillbaka till applikationen, så vet du vilka/hur många kolumner som kommer tillbaka, att de kolumnerna inte har ändrat namn, och i vilken ordning kolumnerna kommer. Om det är en stor tabell och du vill ha alla kolumner så genererar SSMS lätt den frågan åt dig, högerklicka på tabellen och välj "Select from" eller liknande.

Åfan! Skall testa ändra det. Sant ju, på mitt menyval add person vill jag ju lägga till en person efter input i databasen, nu vill jag ju få ut en redan inlagd person så makes sence att det är input.

Okej, tror jag är med, menar du att de bör va exempelvis:
SELECT person_firstname, person_lastname, osv...
FROM Person
Istället för SELECT * ?

Permalänk
Medlem
Skrivet av PapaDiouf:

Okej, tror jag är med, menar du att de bör va exempelvis:
SELECT person_firstname, person_lastname, osv...
FROM Person
Istället för SELECT * ?

Ja. Så länge man inte ändrar i databasen så spelar det ju ingen roll, men om man skulle lägga till en kolumn mitt i tabellen och glömmer att ändra applikationskoden så kan det bli väldigt okul.

Permalänk

Fick till det äntligen, mycket skönt. Som vanligt är det ju enklare än man tror men man får ju helt enkelt börja nånstans!
Nu tkr jag att jag har koll på en del viktiga bitar, nu blir nästa moment att få ihop flera tables!

Permalänk

Tjena igen! Sitter och pillar lite och försöker göra om gamla uppgifer i uppdaterade versioner, denna gång genom att använda databas. Denna uppgiften handlar om att skapa en parkeringsplats, där det finns en meny som användaren kan använda för att lägga till bilar, ta bort bilar, osv!
Har lite svårt med menyvalet där man lägger till ett fordon, inte att inserta info som användaren skriver in, men att skriva en stored procedure som väljer första bästa parkeringsplats för fordonet. Tips på hur jag kan gå tillväga?
I vanlig c# kod hade jag haft en array eller lista och loopat igenom och om platsen är null så hade jag slängt in fordonet där liksom. Men är lite svårare med sql(än så länge)..