C#, Lagrade procedurer och parametrar i VS

Permalänk
Medlem

C#, Lagrade procedurer och parametrar i VS

Hej!

Jag försöker göra en hemsida där användaren ska kunna beställa varor med ett litet formulär hjälp av ett par textboxar. Efter att man har matat in det man vill ha ska databasen uppdateras med det nya saldot på varan. Jag har två tabeller i databasen.

Jag har skapat tabellerna och även en lagrad procedur som skall sköta detta.

Lagrade proceduren:

CREATE PROCEDURE dbo.RemoveProdukt ( @Name nchar(10), @Styck int ) AS BEGIN TRANSACTION SELECT Antal FROM Produkt MINUS SELECT @Styck FROM Produkt WHERE Namn = @Name;

När jag kör detta på VS så funkar det bra. Jag matar in namnet på varan och antal. Därefter uppdateras saldot.

Det jag dock undrar är hur ska jag göra så att det ska kunna köras på en hemsida?

Tidigare hade jag ett formulär på en sida där man la till varor i databasen. Då gjorde jag det med hjälp av parametrar som såg ut såhär:

myCommand.Parameters.Add("@ID", SqlDbType.UniqueIdentifier).Value = System.Guid.NewGuid(); myCommand.Parameters.Add("@Name", SqlDbType.NChar).Value = tbProdukt.Text; myCommand.Parameters.Add("@Styck", SqlDbType.Int).Value = tbAntal.Text; myCommand.Parameters.Add("@MärkeID", SqlDbType.UniqueIdentifier).Value = System.Guid.NewGuid(); myCommand.Parameters.Add("@MärkeNamn", SqlDbType.NChar).Value = tbMärke.Text; myCommand.Parameters.Add("@Varunummer", SqlDbType.NChar).Value = tbVarunummer.Text;

Men hur gör jag för att minska på varorna?

Permalänk
Medlem

Ett tips använd inte stored procedures. Varför? De är väldigt specifika för ändamålet, bättre med mer generalitetet. Detta gör att du kan återanvända mycket om ett liknande problem skulle återkomma.

Permalänk
Medlem
Skrivet av vajjan:

Ett tips använd inte stored procedures. Varför? De är väldigt specifika för ändamålet, bättre med mer generalitetet. Detta gör att du kan återanvända mycket om ett liknande problem skulle återkomma.

Applikationen måste innehålla transaktionshantering och som jag förstått hela rätt så måste detta göras inne i stored procedures. Applikationen ska kunna lägga till data i två tabeller och även radera data.

Jag har lyckats fixa så att man kan lägga till data. Dock vet jag inte hur jag ska göra för radera data från tabellerna.
Går det att att ta bort data med parametrar? Har försökt med det, men det blir helt fel.

Några tips på hur eller vad jag kan använda mig utav?

Permalänk
Medlem
Skrivet av vajjan:

Ett tips använd inte stored procedures. Varför? De är väldigt specifika för ändamålet, bättre med mer generalitetet. Detta gör att du kan återanvända mycket om ett liknande problem skulle återkomma.

Lagrade procedurer är bättre och säkrare sätt använda än vanliga insert. Dels så kan man innan det sparas till tabell formatera om data och man kan också kontrollera data innan det lagras.

Skrivet av Ice7:

Applikationen måste innehålla transaktionshantering och som jag förstått hela rätt så måste detta göras inne i stored procedures. Applikationen ska kunna lägga till data i två tabeller och även radera data.

Jag har lyckats fixa så att man kan lägga till data. Dock vet jag inte hur jag ska göra för radera data från tabellerna.
Går det att att ta bort data med parametrar? Har försökt med det, men det blir helt fel.

Några tips på hur eller vad jag kan använda mig utav?

Har du ingen främmande nyckel mellan dina tabeller? Isf kan du använda den och göra en join.
För att ta bort en rad ifrån flera tabeller kan du använda lagrade procedurer eller krångla till det med manuella transaktioner.

Men som sagt, en främmande nyckel tror jag är din lösning.
(Personer)
_Id | FNamn | ENamn
1 | Nomen | Notetur
(Bilar)
_id | modell | tillverkare | PId (ägare)
1 | Lorem | Ipsum | 1

Id är två primära nycklar för respektive tabell och PId är en främmande nyckel med relation till Personer.Id

Då kan du köra två delete from i en procedur på personer.id!

Edit: får att få det till en hemsida så får du göra om ditt projekt till ett ASP.NET projekt!

Visa signatur

~. Citera så jag hittar tillbaka .~

Permalänk
Medlem
Skrivet av KeVVa:

Lagrade procedurer är bättre och säkrare sätt använda än vanliga insert. Dels så kan man innan det sparas till tabell formatera om data och man kan också kontrollera data innan det lagras.

Har du ingen främmande nyckel mellan dina tabeller? Isf kan du använda den och göra en join.
För att ta bort en rad ifrån flera tabeller kan du använda lagrade procedurer eller krångla till det med manuella transaktioner.

Men som sagt, en främmande nyckel tror jag är din lösning.
(Personer)
_Id | FNamn | ENamn
1 | Nomen | Notetur
(Bilar)
_id | modell | tillverkare | PId (ägare)
1 | Lorem | Ipsum | 1

Id är två primära nycklar för respektive tabell och PId är en främmande nyckel med relation till Personer.Id

Då kan du köra två delete from i en procedur på personer.id!

Edit: får att få det till en hemsida så får du göra om ditt projekt till ett ASP.NET projekt!

Jag ska försöka förklara min applikation tydligare så ni får en bättre bild på hur den ser ut.

Först skapade jag två Tabeller i databasen: Märke och Produkt

Märke

-ID (Primärnycker) UNIQUEIDENTIFIER
-Märke NCHAR
-Varunummer NVARCHAR

Produkt

-ID (Primärnyckel) UNIQUEIDENTIFIER
-Namn NCHAR
-Antal INT
-MärkeID (Främmande nyckel) UNIQUEIDENTIFIER

Därefter skapade jag en lagrad procedur som såg till att man kunde lägga till data i tabellerna.

Lagrad procedur AddMärkeAndProdukt

( @ID uniqueidentifier, @Name nchar(10), @Styck int, @MärkeID uniqueidentifier, @MärkeNamn nchar(10), @Varunummer nchar(10) ) AS BEGIN TRANSACTION -- Steg 2 lägger till person och familj till den personen i samma transaktion INSERT INTO Produkt (ID, Namn, Antal, MärkeID) values (@ID, @Name, @Styck, @MärkeID); IF @@ERROR <> 0 BEGIN ROLLBACK RETURN END INSERT INTO Märke (ID, Märke, Varunummer) values (@MärkeID, @MärkeNamn, @Varunummer); IF @@ERROR <> 0 BEGIN ROLLBACK RETURN END COMMIT

Inga problem alls med denna procedur.

Efter detta skapade jag en aspx sida

Jag ville kunna göra samma sak genom att jag fyller i värden i ett par textboxar på en sida och matar in dessa i databasen.

När jag klickade på knappen Lägg till så skulle datan matas in

Koden:

SqlConnection myConnection = new SqlConnection(); myConnection.ConnectionString = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString; SqlCommand myCommand = new SqlCommand("AddMärkeAndProdukt", myConnection); myCommand.CommandType = CommandType.StoredProcedure; // Skapar parametrar att passa mot lagrad procedur. Value är alltså det som finns i textboxen myCommand.Parameters.Add("@ID", SqlDbType.UniqueIdentifier).Value = System.Guid.NewGuid(); myCommand.Parameters.Add("@Name", SqlDbType.NChar).Value = tbProdukt.Text; myCommand.Parameters.Add("@Styck", SqlDbType.Int).Value = tbAntal.Text; myCommand.Parameters.Add("@MärkeID", SqlDbType.UniqueIdentifier).Value = System.Guid.NewGuid(); myCommand.Parameters.Add("@MärkeNamn", SqlDbType.NChar).Value = tbMärke.Text; myCommand.Parameters.Add("@Varunummer", SqlDbType.NChar).Value = tbVarunummer.Text;

Även här var det inga problem. Och det gick att mata in via webbsidan.

Jag vill kunna göra samma sak fast att den ska minska på antalet produkter.

Exempel:

Vi antar att jag har 4 paket pasta från Barilla i databasen. Om jag via websidan beställer 2 paket pasta från Barilla så ska det visa i databasen att det är 2 paket kvar av pastan.

Jag ska skapade en Lagrad procedur "RemoveProdukt" till detta:

( @Name nchar(10), @Styck int ) AS BEGIN TRANSACTION SELECT Antal FROM Produkt MINUS SELECT @Styck FROM Produkt WHERE Namn = @Name;

Även denna fungerar bra när jag exikverar den och antalet blir korrekt. Men hur får jag den att fungera med textboxar.
När jag la till varor så använde jag mig av Parameters.Add för att kopplade det till textboxarna, men vad kan jag använda mig av när jag ska ta bort varor.

Ursäkta om texten blev för lång

Permalänk

Transaktionshantering kan man sköta direkt i .Net om man inte vill hålla på med procedurer. Fast om man ska köra old school är procedurer bättre än inline-sql tycker jag...

MEN, du borde satsa på ett ORM, Entity Framework är busenkelt att komma igång med

Permalänk
Medlem
Skrivet av Ice7:

Applikationen måste innehålla transaktionshantering och som jag förstått hela rätt så måste detta göras inne i stored procedures. Applikationen ska kunna lägga till data i två tabeller och även radera data.

Jag har lyckats fixa så att man kan lägga till data. Dock vet jag inte hur jag ska göra för radera data från tabellerna.
Går det att att ta bort data med parametrar? Har försökt med det, men det blir helt fel.

Några tips på hur eller vad jag kan använda mig utav?

Jag använder EF. Finns mycket bra tutorials, bl.a denna

Permalänk
Medlem

Jag kommer titta djupare in på EF efter att jag fixat detta. Verkar vara smidigare. Men när jag nu håller på och det känns som att jag närmar mig att lösa det på ett "old school" sätt så vill jag inte ge upp ännu. Det är även bra om jag lär mig hur man gör på detta sätt också.

Jag testade att skriva parametrarna såhär nu. Och när jag fyller i värdena på webbsidan och klickar på beställ så kommer texten "Uppdateringen lyckades"
Denna text ska alltså komma upp om det har gått som det ska. När jag senare tittar på min produkt tabell så har antalet inte minskats.

Någon som ser vart felet kan vara?

SqlCommand deleteCommand = new SqlCommand("RemoveProdukt", myConnection); deleteCommand.CommandType = CommandType.StoredProcedure; deleteCommand.Parameters.Add("@Name", SqlDbType.NChar).Value = tbProdukt.Text; deleteCommand.Parameters.Add("@Styck", SqlDbType.Int).Value = tbAntal.Text;

Permalänk
Skrivet av Ice7:

Jag kommer titta djupare in på EF efter att jag fixat detta. Verkar vara smidigare. Men när jag nu håller på och det känns som att jag närmar mig att lösa det på ett "old school" sätt så vill jag inte ge upp ännu. Det är även bra om jag lär mig hur man gör på detta sätt också.

Jag testade att skriva parametrarna såhär nu. Och när jag fyller i värdena på webbsidan och klickar på beställ så kommer texten "Uppdateringen lyckades"
Denna text ska alltså komma upp om det har gått som det ska. När jag senare tittar på min produkt tabell så har antalet inte minskats.

Någon som ser vart felet kan vara?

SqlCommand deleteCommand = new SqlCommand("RemoveProdukt", myConnection); deleteCommand.CommandType = CommandType.StoredProcedure; deleteCommand.Parameters.Add("@Name", SqlDbType.NChar).Value = tbProdukt.Text; deleteCommand.Parameters.Add("@Styck", SqlDbType.Int).Value = tbAntal.Text;

MSDN skriver parametervärdet på en egen rad:

command.Parameters.Add("@ID", SqlDbType.Int); command.Parameters["@ID"].Value = customerID;

Värt att testa?
Tror inte du kan tilldela parametervärdet på det sättet du gör nämligen.

Permalänk
Medlem
Skrivet av Magnetize:

MSDN skriver parametervärdet på en egen rad:

command.Parameters.Add("@ID", SqlDbType.Int); command.Parameters["@ID"].Value = customerID;

Värt att testa?
Tror inte du kan tilldela parametervärdet på det sättet du gör nämligen.

Testade att skriva på det sättet, får samma felmeddelande. Jag tror inte att det är något fel att skriva parametrarna som jag gjorde innan för att jag kan lägga till värden. Dock har jag inte lyckats klura ut hur jag får dom att ta bort varor i databasen.

Jag ändrade dock min procedur RemoveProdukt till:

( @ID Uniqueidentifier, @Name nchar(10), @Styck int ) AS BEGIN TRANSACTION UPDATE Produkt SET Antal = @Styck WHERE ID =@ID;

När jag exekverar den i VS så fyller jag i ID, Namn och Styck. Och det funkar fint.

När jag gör det på webbsidan så får jag följande felmeddelande: "Failed to convert parameter value from a String to a Guid"

Parametrar:

deleteCommand.Parameters.Add("@ID", SqlDbType.UniqueIdentifier).Value = tbID.Text; deleteCommand.Parameters.Add("@Name", SqlDbType.NChar).Value = tbProdukt.Text; deleteCommand.Parameters.Add("@Styck", SqlDbType.Int).Value = tbAntal.Text;

Någon som vet hur man kan konvertera det jag matar in i textboxen och få det att matcha med ID?

Permalänk
Medlem

deleteCommand.Parameters.Add("@ID", SqlDbType.UniqueIdentifier).Value = new Guid(tbID.Text);

förutsatt att tbID.Text är en korrekt guid, guids är inte speciellt bra ids att använda för saker där man manuellt behöver skriva in dem där är vanliga integers bättre då de är lättare att skriva rätt

Visa signatur

Fractal Design Node 304 -> ASUS ROG STRIX Z370-I GAMING ->i5 8600K -> be quiet! Pure Rock -> MSI GeForce RTX 4070 VENTUS 2X E 12G OC -> Corsair Vengeance LPX 3200 32GB -> Seasonic FOCUS Plus 650W Gold -> Samsung 960 EVO 500GB -> 2 * Western Digital Black 2 TB -> Samsung 850 EVO Basic SSD 500GB

Permalänk
Medlem
Skrivet av Verdurakh:

deleteCommand.Parameters.Add("@ID", SqlDbType.UniqueIdentifier).Value = new Guid(tbID.Text);

förutsatt att tbID.Text är en korrekt guid, guids är inte speciellt bra ids att använda för saker där man manuellt behöver skriva in dem där är vanliga integers bättre då de är lättare att skriva rätt

Tusen tack! Nu fungerar den äntligen