How to create a stored procedure in ADO.NET - c#

I have the following code and i would like it to be a stored procedure.
How do you create and call a stored procedure so that the following code is just like a method call.
Where are stored procedure stored are they created in Visual studio or in MS SQL Server?
using (var conn = new SqlConnection(dbConnectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText =
#"use [Email Database]
INSERT INTO Emails_Log
(Email_ID, e_To, e_From, e_Subject, e_Date)
VALUES
(#id, #to, #from, #subject, #date)";
// Writes to database (local) instance
cmd.Parameters.AddWithValue("#id", emailID);
cmd.Parameters.AddWithValue("#to", emailTo);
cmd.Parameters.AddWithValue("#from", emailFrom);
cmd.Parameters.AddWithValue("#subject", emailSubject);
cmd.Parameters.AddWithValue("#date", emailSentDate);
cmd.ExecuteNonQuery();
}
NEW QUESTION!
I have managed to Create a Stored Procedure thanks guys, I'm just left with one more Problem.
cmd.CommandType = CommandType.StoredProcedure;
There is a red line under the second CommandType and the error reads
The name 'CommandType' does not exist in the current context
Please help.

On your server Create a procedure using the code below:
CREATE PROCEDURE InsertProc
(
#id <put here the datatype>,
#to <put here the datatype>,
#from <put here the datatype>,
#subject <put here the datatype>,
#date <put here the datatype>
)
AS
INSERT INTO Emails_Log (Email_ID, e_To, e_From, e_Subject, e_Date)
VALUES (#id, #to, #from, #subject, #date)
after you have created the procedure, in your code try this:
// other codes
cmd.CommandText = "InsertProc";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#id", emailID);
cmd.Parameters.AddWithValue("#to", emailTo);
cmd.Parameters.AddWithValue("#from", emailFrom);
cmd.Parameters.AddWithValue("#subject", emailSubject);
cmd.Parameters.AddWithValue("#date", emailSentDate);
cmd.ExecuteNonQuery();

Most commonly, you would have a sql script (or a series of incremental scripts) that you can apply to your server, creating the objects including things like sprocs; then, just (perhaps in SSMS):
use [Email Database]
create proc SomeNameHere
-- note these lengths are made up
#id int, #to nvarchar(400), #from nvarchar(400),
#subject nvarchar(2000), #date datetime
as
INSERT INTO Emails_Log
(Email_ID, e_To, e_From, e_Subject, e_Date)
VALUES
(#id, #to, #from, #subject, #date)
go
however! I would also say "why make that a sproc?" - unless you have a good reason, I genuinely challenge the thought that everything must be a sproc. In particular, it makes maintenance (especially in a deployment scenario where different servers may be at different stages) harder. Sprocs are good when you want to do non-trivial processing, don't want to transport lots of data over the wire, and it has non-trivial length - but I personally wouldn't use one just for this insert, unless it was strict local policy.
Then, in your command, set the CommandType to be stored procedure, and set "SomeNameHere" as the CommandText.

Stored procedures are stored in sql server. First you have to create the stored procedure in sql server. here you can see how to create a stored procedure. Then you need to call the stored procedure in c# here you can see how you can call stored procedures that are saved in ms sql server. hope it helps.

The error "The name 'CommandType' does not exist in the current context" is caused by a missing namespace. Just add "using System.Data;" on top and it will work.

Related

C# invalid column name problem but is different from others

Hello i have a table called Card_tbl with a cell CardID. The problem is that when i insert only numbers like 12345 they are uploaded in the database, but when i use mix letters like Q1234R it will say INVALID COLUMN NAME Q1234R I tried many things to fix it but no success.
THE CELL IS ON VARCHAR(50) this is my code
Con.Open();
SqlCommand cmd = new SqlCommand("insert into Card_tbl values(" +txtCardNumber.Text+")", Con);
cmd.ExecuteNonQuery();
MessageBox.Show("Admin Successfully Added!");
Con.Close();
populate();
//updateroomstate();
Clean();
the error is shown here cmd.ExecuteNonQuery();
Thank you in advance.
Solution
The correct solution is to use prepared statements. You've said the column is a varchar(50) so:
using (SqlConnection conn = new SqlConnection("yourconnectionstring"))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO Card_tbl VALUES (#cardNumber)", conn))
{
// we specify type VarChar and size 50, because your column is a varchar(50)
cmd.Parameters.Add("#cardNumber", SqlDbType.VarChar, 50).Value = txtCardNumber.Text;
cmd.ExecuteNonQuery();
}
}
I would also recommend that you specify the column name for the insert:
INSERT INTO Card_tbl (CardId) VALUES (#cardNumber) -- I've assumed that the column is called CardId
Why do we need parameterized queries / prepared statements?
The reason we need prepared statements is because the user could enter something malicious in the query, forcing your server to execute queries that you didn't intend.
If you have a query like this, SQL Server will do the insert and then drop the table:
INSERT INTO MyTable VALUES ('hello'); DROP TABLE MyTable; -- comment
This is a multi-statement query, meaning that the INSERT will be done first, and then the DROP TABLE will be executed. The -- denotes a comment, and everything after that in the query is discarded.
Now, if you build a query like "INSERT INTO MyTable VALUES ('" + someUserInput + "')", how could a malicious user make this query more like the previous one? Simple: enter SQL into their input.
Suppose someUserInput is '); DROP TABLE MyTable; -- comment then your query will become:
INSERT INTO MyTable VALUES(''); DROP TABLE MyTable; -- comment')
Like this, a malicious user can perform an extremely destructive operation on your database, bypass login pages, expose secret information, etc. This is a huge risk for your application.
Prepared statements work by separating the query text from the parameter values. Because they're not part of the query, they can't be interpreted as SQL. It also means that binary data types can be sent to the server as binary rather than as text. Example: DateTime.
Try this instead
Insert into Card_tbl(CardID) values('" +txtCardNumber.Text+"')"
https://www.w3schools.com/sql/sql_insert.asp

SQL Stored Procedure error by updating

Im trying to use a stored procedure with parameter, in this case the OrderID.
But i'm getting the error : 'Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).'
My C# methode:
using (SqlCommand cmd = new SqlCommand("UpdateStock", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#OrderID", SqlDbType.Int).Value = OrderId;
cmd.ExecuteNonQuery();
}
My Stored Procedure:
CREATE PROCEDURE [dbo].[UpdateStock] #OrderID int
AS
BEGIN
UPDATE Products SET Stock = Stock -1 FROM Products INNER JOIN
OrderDetails ON
Products.ProductId = OrderDetails.ProductID WHERE OrderDetails.OrderID =
#OrderID
END
GO
Maybe you guys can help me out?
Looking at the code you provided so far looks fine. However the error is saying something like - somewhere, a stored procedure is calling another stored procedure and then again and again.. too many times. It could also mean that there is 1 stored procedure calling itself too many times.
So the provided code doesn't show this behavior so I would suggest looking elsewhere. As mentioned in the comments a good place to look are the triggers on the Products table. A trigger might run when you try to update it which could be the root of the problem.

Getting error message when trying to execute code [duplicate]

This question already has answers here:
Column name or number of supplied values does not match table definition
(16 answers)
Closed 9 years ago.
con.Open();
string qry="insert into reg1 values ('"+txtname.Text+"','"+txtaddress.Text+"','"+txtpin.Text+"','"+txtage.Text+"','"+txtgender.Text+"','"+txtcourse.Text+"','"+txtcollege.Text+"','"+txtfname.Text+"','"+txtoccup.Text+"','"+txtmname.Text+"','"+txtskills.Text+"','"+txtmobile.Text+"','"+txtemail.Text+"')";
SqlCommand cmd = new SqlCommand(qry, con);
cmd.ExecuteNonQuery();
con.Close();
I am receiving the following error message when I try to execute this code:
Column name or number of supplied values does not match table definition.
Can anyone help me find the error?
Sounds like your column numbers in your table and your SqlCommand does not match. But since we didn't know anything about your table design, we never know..
If your INSERT command and your table doesn't have the same column number, you have to declare your column names which you want to insert these values..
I count 14 columns on your table from your comment, but you try to add 13 values. These are doesn't match.
But more important, you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
con.Open();
string qry = #"insert into reg1
values(#name, #address, #pin, #age, #gender, #course, #college, #fname
#occup, #mname, #skills, #mobile, #email)";
SqlCommand cmd = new SqlCommand(qry, con);
cmd.Parameters.AddWithValue("#name", txtname.Text);
cmd.Parameters.AddWithValue("#address", txtaddress.Text);,
.....
cmd.ExecuteNonQuery();
con.Close();
you entered to much or to few values into the table in other words your table has 5 columns and you entered 6 values or 4 check that the values you entered corresponds with your table
best advice i can give is always use a procedure it is recommended to protect against sql injection and it will reduce the chance of this happening ,it is also a lot more efficient than hard coding it from c# end
create a proc and just call it from c# end done ;)
SQL Server stored procedure beginner's guide
create proc example_insert
#values varchar(100) <--- declare parameters
as
insert into [Table]([Column],[Column],[Column])
values('','','',)<--- -this should be the same number as your columns
calling the stored procedure this is in vb but the principle is the same
s1.Open() 'opens the connection
Dim cmd As New SqlCommand("example_insert", s1)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#Value", textbox.Text)<--- a lot simpler

How to create a stored procedure that inserts data into a table from a Visual Studio Application

The code I have given is what I have now in my button click event, but instead of directly inputting the SQL statement I need to use a stored procedure. So basically I need to convert this code from Visual Studio 2010 into a stored procedure in SQL Server 2008.
command.Connection = conn;
command.CommandType = CommandType.Text;
command.CommandText = **"INSERT INTO Customer VALUES(" + txtCustID.Text + ",'"+ txtFirstName.Text + "', '" + txtSurname.Text + "', " + txtAge.Text + ")";**
command.Connection.Open();
adapter.InsertCommand = command;
adapter.InsertCommand.ExecuteNonQuery();
command.Connection.Close();
Clear();
Here is what you need to do. Note I have not tested this code out but you should be close. You might need to tweak it with intellisense.
1) In SQL Server Management Studio open a New Query Editor Window by doing CTRL-N
2) Start each procedure with the following
CREATE Procedure ProcedureName
--Add Any Parameters that you will be passing in this way:
#parameterName datatype
--Add any additional parameters as needed by adding a comma at the end of the previous line
--And adding a new one : #parameterName datatype, #parameterName2 datatype
AS
BEGIN
--Here is where your write your stored procedure:
INSERT INTO Customer (custId, firstname, surname, age)
VALUES(#custId,#firstname, #surname, #age)
END
3) In SQL Server Management Studio, execute the script. Your stored procedure is now saved in SQL You can always call it using exec sprocName parameter1, parameter 2.... If you need to pull it back up again to edit it, you simply go into Programmability --> Stored Procedures, find the procedure and right click and MODIFY. If you hit execute it will make the changes you made.
4) in your .NET Code do this:
command.Connection = conn;
command.CommandType = CommandType.StoredProcedure; //Look up the actual code using intellisense as I dont recall what CommandType a stored Procedure is.
command.paramaters.addwithvalue (#age, txtAge.text) //using this as an example. Youw ill actually need to put in the same variables declared in SQL and where they correspond to on the screen.
command.Connection.Open();
adapter.InsertCommand = command;
adapter.InsertCommand.ExecuteNonQuery();
command.Connection.Close();
Clear();
If you notice, there is a parameters.addwithvalue part. This is the best way to pass parameters to the stored procedure. No reason to worry about apostrophes (you still need commas of course). Its far safer and will reduce risk of SQL Injection Attack (a way for people to enter code into your app and make it do really bad things to SQL Server)
I hope this helps... good luck!
You simply create a stored procedure by writing your procedure code in a 'New Query' window of Sql MAnagement Studio.
For example you code could be:
-- drop the procedure if it exists
-- in order to recreate it
if object_id('usp_newCustomer') is not null
drop procedure usp_newCustomer
go
-- procedure new customer
create procedure usp_NewCustomer
-- parameters of the procedure
#custID integer,
#firstName nvarchar(32),
#surName nvarchar(32),
#age integer
as
-- code of the procedure
begin
-- insert into cutomer the values passed as parameters
insert into Customer( custId, firstName, surName, age )
values (#custId, #firstNAme, #surName, #age );
end
and in your application instead of doing the insert (in command.text) you can call your procedure with:
exec usp_NewCustomer 1, 'Johny', 'BeGood', 85
You can try one of the following ways
At first Create and Run a SQL Server Stored Procedure by using Common Language Run-time Integration and then execute this procedure from your application as EXEC procedureName
Or
instead create your stored procedure using sql server management studio and execute the procedure from your application like
exec storedProcedureName
Thanks

Parameter Binding: What happens under the hood?

.NET, Java and other high level database API's in various language often provide techniques known as prepared statements and parameter binding as opposed to sending plain text commands to the Database server. What I would like to know is what happens when you execute a statement like this:
SqlCommand cmd = new SqlCommand("GetMemberByID");
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter("#ID", memberID);
para.DbType = DbType.Integer;
cmd.Parameters.Add(param);
I know this is a best practice. SQL injection attacks are minimized this way. But what exactly happens under the hood when you execute these statements? Is the end result still a SQL safe string? If not, what is the end result? And is this enough to prevent SQL injection attacks?
The MySQL manual page on prepared statements provides lots of information (which should apply to any other RDBMS).
Basically, your statement is parsed and processed ahead of time, and the parameters are sent separately instead of being handled along with the SQL code. This eliminates SQL-injection attacks because the SQL is parsed before the parameters are even set.
in layman terms: if a prepared statement is sent then the DB will use a plan if it is available, it doesn't not have to recreate a plan every time this query is sent over but only the values of the params have changed. this is very similar to how procs work, the additional benefit with procs is that you can give permission through procs only and not to the underlying tables at all
If you're using MS SQL, load up the profiler and you'll see what SQL statements are generated when you use parameterised queries. Here's an example (I'm using Enterprise Libary 3.1, but the results are the same using SqlParameters directly) against SQL Server 2005:
string sql = "SELECT * FROM tblDomains WHERE DomainName = #DomName AND DomainID = #Did";
Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
db.AddInParameter(cmd, "DomName", DbType.String, "xxxxx.net");
db.AddInParameter(cmd, "Did", DbType.Int32, 500204);
DataSet ds = db.ExecuteDataSet(cmd);
}
This generates:
exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = #DomName AND DomainID = #Did',
N'#DomName nvarchar(9),
#Did int',
#DomName=N'xxxxx.net',
#Did=500204
You can also see here, if quotation characters were passed as parameters, they are escaped accordingly:
db.AddInParameter(cmd, "DomName", DbType.String, "'xxxxx.net");
exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = #DomName AND DomainID = #Did',
N'#DomName nvarchar(10),
#Did int',
#DomName=N'''xxxxx.net',
#Did=500204

Categories

Resources