I am trying to insert values into my SQL database, the query works on the SQL side but when it comes to implement it from C# ASP.NET, it will not insert anything into the SQL database. The code is as follows:
public partial class About : Page
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
}
protected void Button1_Click(object sender, EventArgs e)
{
SqlCommand cmd = new SqlCommand("insert into sanctuary(SName) values('test')", con);
cmd = new SqlCommand("insert into species(Name) values('test1')", con);
cmd = new SqlCommand("insert into breed(SpeciesID, BreedName, FoodCost, HousingCost) SELECT SpeciesID, ('breed'), ('12'), ('21') FROM species", con);
cmd.ExecuteNonQuery();
con.Close();
}
}
}
Your help will be much appreciated!
If you want to execute three commands together you merge the sql of the three commands in a single string separating them with a semicolon (See Batch of Sql Commands)
string cmdText = #"insert into sanctuary(SName) values('test');
insert into species(Name) values('test1');
insert into breed(SpeciesID, BreedName, FoodCost, HousingCost)
SELECT SpeciesID, ('breed'), ('12'), ('21') FROM species";
SqlCommand cmd = new SqlCommand(cmdText, con);
cmd.ExecuteNonQuery();
The first problem in your code is that you need to execute each single command and not just the last one. Finally, if you don't see even the insert for the last command could be because your table species is empty and thus the final command has nothing to insert.
Last note, the point underlined by Zohar Peled about NOT keeping a global connection object around, is very important, follow the advice.
You only execute the last command, so there is nothing in species. Since there is nothing in species, the select returns no results so nothing gets inserted into breed.
Also, keeping an SqlConnection object on the page level is not a good idea. SQL connections should be opened right before executing queries and disposed immediately after.
A better code would look like this:
using(var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
using(var com = new SqlCommand("insert into sanctuary(SName) values('test');insert into species(Name) values('test1');insert into breed(SpeciesID, BreedName, FoodCost, HousingCost) SELECT SpeciesID, ('breed'), ('12'), ('21') FROM species", con)
{
con.Open();
com.ExecuteNonQuery();
}
}
You can, of course, execute each SQL statement separately (though in this case it's not the best course of action since it means 3 round trips to the database instead of just one):
using(var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
using(var com = new SqlCommand("insert into sanctuary(SName) values('test');", con)
{
con.Open();
com.ExecuteNonQuery();
com.CommandText = "insert into species(Name) values('test1');";
com.ExecuteNonQuery();
com.CommandText = "insert into breed(SpeciesID, BreedName, FoodCost, HousingCost) SELECT SpeciesID, ('breed'), ('12'), ('21') FROM species;";
com.ExecuteNonQuery();
}
}
Related
Every time I try to run my code, I get this exception:
An unhandled exception of type 'System.Data.SqlClient.SqlException'
occurred in System.Data.dll
Additional information: Incorrect syntax near ')'.
Tried multiple workarounds, but I never get past the ExectueNonQuery line. Can someone tell me what's wrong with it?
private void button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(#"Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;");
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES ('"+idFis.Text+ "','"+ numeFis.Text + "','" +idFoldFis.Text +"',)", con);
cmd.ExecuteNonQuery();
con.Close();
}
While the other questions state the root problem, your trailing comma, you really must do better about your queries. Do not glue your query together like that, use parameters instead. If you do not you are opening yourself to huge security problems. Also you really must put the connection in a using statement so when a error does happen the connection will still be closed.
private void button1_Click(object sender, EventArgs e)
{
using(SqlConnection con = new SqlConnection(#"Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;"))
{
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES (#idFis,#numeFis,#idFoldFis)",con);
cmd.Parameters.Add("#idFis", SqlDbType.NVarChar, -1).Value = idFis.Text;
cmd.Parameters.Add("#numeFis", SqlDbType.NVarChar, -1).Value = numeFis.Text;
cmd.Parameters.Add("#idFoldFis", SqlDbType.NVarChar, -1).Value = idFoldFis.Text;
cmd.ExecuteNonQuery();
}
}
The comma is your problem, but I would recommend a few other changes at least before moving on:
Don't embed your connection strings into each db connection request. Use app.config/web.config or anything else :)
Ensure your connections are commands are properly disposed of
Parameterize any SQL queries to prevent injection attacks
Abstract database commands into separate business layer
1. Utilize an "app.config" for connection strings
There are many docs out there on keeping a connection string secure, but at a minimum, don't embed straight into each of your connection code.
Add an "app.config" to your client project (or utilize the web.config of web projects). At a minimum, this looks like this:
<configuration>
<appSettings>
<add key="db" value="Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;" />
</appSettings>
</configuration>
Then add a reference to "System.Configuration" to your project, and you can reference it like this in your code:
var con = new SqlConnection(ConfigurationManager.AppSettings["db"]);
2. Ensure your connections ard commands are properly disposed
Wrap connections and commands in using. Here is an example:
using (var con = new SqlConnection(ConfigurationManager.AppSettings["db"]))
{
con.Open();
var sql = "/* My command here */";
using (var cmd = new SqlCommand(sql, con))
{
// SQL execution here
}
} // Closing is now handled for you (even if errors occur)
3. Parameterize any SQL queries to prevent injection attacks
Concatenating strings are very dangerous for SQL commands (just google "SQL Injection"). This is how to protect yourself.
using (var con = new SqlConnection(ConfigurationManager.AppSettings["db"]))
{
con.Open();
var sql = "INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES (#idFisier, #nume, #idFolder)";
using (var cmd = new SqlCommand(sql, con))
{
cmd.Parameters.Add("#idFisier", SqlDbType.VarChar).Value = idFis.Text;
cmd.Parameters.Add("#nume", SqlDbType.VarChar).Value = numeFis.Text;
cmd.Parameters.Add("#idFolder", SqlDbType.VarChar).Value = idFoldFis.Text;
cmd.ExecuteNonQuery();
}
} // Closing is now handled for you (even if errors occur)
4. Abstract database commands into separate business layer
It is usually best practice and will save you many headaches by writing separate classes (even class library) as your business layer that only contain your data commands. Then your UI would only handle calling the business layer methods.
If your database ever changes or you need to do similar functionality in other parts of your UI, it won't be very fun updating the same query all over your UI as opposed to just updating a single spot in your business layer.
Make SQL being readable and parametrized and you'll find the routine easy to implement:
// Extract a method (or even a class): do not mix UI and business logic/storage
// Just RDBMS logic: no UI controls or something at all
private static void CoreInsertFisier(string idFisier, nume, idFolder) {
// Do not hardcode the connection string, but read it (from settings)
// wrap IDisposable into using
using (SqlConnection con = new SqlConnection(ConnectionStringHere)) {
con.Open();
// Make sql readable (use verbatim strings #"...")
// Make sql parameterized
string sql =
#"INSERT INTO Fisier (
idFisier,
Nume,
idFolder)
VALUES (
#prm_idFisier,
#prm_Nume,
#prm_idFolder)";
// wrap IDisposable into using
using (SqlCommand cmd = new SqlCommand(sql, con)) {
// Parameters.Add(...) is a better choice, but you have to know fields' types
cmd.Parameters.AddWithValue("#prm_idFisier", idFisier);
cmd.Parameters.AddWithValue("#prm_Nume", nume);
cmd.Parameters.AddWithValue("#prm_idFolder", idFolder);
cmd.ExecuteNonQuery();
}
}
}
...
private void button1_Click(object sender, EventArgs e) {
// UI: just one call - please insert these three textbox into db
CoreInsertFisier(idFis.Text, numeFis.Text, idFoldFis.Text);
}
You have an extra trailing comma:
private void button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(#"Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;");
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES ('"+idFis.Text+ "','"+ numeFis.Text + "','" +idFoldFis.Text +"')",con);
cmd.ExecuteNonQuery();
con.Close();
}
Anyway as others said, it is a very bad idea to concatenate your query that way, since it could lead you to have sql injection on your code.
Try removing the , before the closing )
SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES ('"+idFis.Text+ "','"+ numeFis.Text + "','" +idFoldFis.Text +"')",con);
I am building an application for a group of friends and myself to use for DnD sessions. Part of the program involves taking all of the values that are entered for our characters, items, etc and storing them to a database. I have the database built, and am pulling from the database into the program, however I am unable to return data to the database. I have the data coming into a dataset, and all of my edits are affecting the dataset, but I cannot get anything to affect the actual source database tables.
Below I have the button that I intend to use to update items in the characters' packs. I have both dataadapter, and tableadapter methods included that I have tried.
private void btnaddpack_Click(object sender, EventArgs e)
{
if (txtbxpack.Text != "")
{
/*connection.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "UPDATE Pack SET Item = (#ItemName)" + "WHERE Id = '" + this.lstpack.SelectedValue + "';";
cmd.ExecuteNonQuery();
cmd.Clone();*/
string packitem = txtbxpack.Text; //will take item from an textbox
this.packTableAdapter.Insert(packitem);
this.Validate();
this.packBindingSource.EndEdit();
this.packTableAdapter.Update(this.dnD_MachineDataSet.Pack);
}
PopulatePack();
Here is my populate code in case someone needs that:
private void PopulatePack()
{
using (connection = new SqlConnection(connectionString)) //this is all about opening the connection to the sqldatabase, normally it would need to be closed, but this uses idisposable, so it will close itself
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Pack", connection))
{
DataTable packtable = new DataTable();
adapter.Fill(packtable);
lstpack.DataSource = packtable;
lstpack.DisplayMember = "Item";
lstpack.ValueMember = "Id";
}
}
As mentioned above, all of the changes are appearing whenever I re-populate the listboxes that draw upon the dataset, hence why this is an issue of trying to get that data back into the source database. I will make the obligatory "I'm relatively new to using databases" statement as it will do no good to pretend that I am an expert.
Thanks.
In the commented code, you would need to do the following:
assign the connection object to the SqlCommand object's Connection
property
pass the item name to your #ItemName parameter
assign a parameter value to the 'Id' column in the WHERE clause
remove, 'cmd.Clone();', and replace with, 'connection.Close();'
Here is what the code should look like:
connection.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandText = "UPDATE Pack SET Item = (#ItemName) WHERE Id = #ID;";
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#ItemName", txtbxpack.Text);
cmd.Parameters.AddWithValue("#ID", this.lstpack.SelectedValue);
cmd.ExecuteNonQuery();
connection.Close();
i want to delete data in my database and using this code but its now working
private static void DeletePreviousRecord()
{
string connectionString = "Data Source=ABDULLAH\\ABDULLAHZAFAR;Initial Catalog=FoodHunt;Integrated Security=True";
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand("Delete From RestaurantsMenu", con))
{
try
{
cmd.CommandType = CommandType.StoredProcedure;
con.Open();
var result = cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{ }
}
}
}
i tried this but this is not working, how can i do that, any suggestion?
Setting the CommandType to StoredProcedure when you clearly use a sql text directly cannot do any good at your code.
Remove that line because the default is CommandType.Text (and this is correct for your command)
But as stated in the comment above.
If you catch the exception, at least write in some log or display at
video what the error message is
If you don't add a WHERE clause at your sql statement, you delete
everything in the table (Probably you are lucky that this code has
not worked)
Looking at your comment below, if you want to delete every record (and reset the Identity column if any) a faster approach is
using (SqlCommand cmd = new SqlCommand("TRUNCATE TABLE RestaurantsMenu", con))
For a quick reading about the difference between TRUNCATE and DELETE look at this article
I'm quite used to using c# with SQL server. I have no idea why a simple statement would fail to insert data. My code is as follows:
query = "INSERT INTO MCDPhoneNumber ([MCDID],[PhoneNumber])" +
"VALUES("+maxid+", '"+tel+"')";
SqlConnection conn = new SqlConnection("Data Source=source; ...");
SqlCommand newCommand = new SqlCommand(query, conn);
int success= myCommand.ExecuteNonQuery();
if (success!= 1)
{
MessageBox.Show("It didn't insert anything:" + query);
}
First of all let me tell that I know that I should use parameters for data and I initially did, but when it failed I tried a simple query and it still fails. For addition I can tell that I have a similar insert just before that one in another table and it works. What's funnier is that when I copy paste query to SQL Server Management Studio it works. It also doesn't report any error in process.
====================== Edit ===============================
If you wish to use old command object (i.e. myCommand) then use following code instead of creating a new command(newCommand)
myCommand.CommandText = query;
myCommand.CommandType = System.Data.CommandType.Text;
And then execute it
you are binding query with newCommand and executing myCommand.
====================== Edit ===============================
SqlCommand newCommand = new SqlCommand(query, conn);
here you have defined newCommand for SQLCOMMAND object
int success= myCommand.ExecuteNonQuery();
and you are accessing it as myCommand
And moreover i think you are not opening connection
First of all, you define your command as newCommand but you executing your myCommand.
You should always use parameterized queries for your sql queries. This kind of string concatenations are open for SQL Injection attacks.
query = "INSERT INTO MCDPhoneNumber (MCDID, PhoneNumber) VALUES(#maxid, #tel)";
using(SqlConnection conn = new SqlConnection("Data Source=source; Initial Catalog=base; Integrated Security = true"))
{
SqlCommand newCommand = new SqlCommand(query, conn);
conn.Open();
newCommand.Parameters.AddWithValue("#maxid", maxid);
newCommand.Parameters.AddWithValue("#tel", tel);
int success= newCommand.ExecuteNonQuery();
if (success != 1)
{
MessageBox.Show("It didn't insert shit:" + query);
}
}
And please be more polite about your error messages :)
I was trying to store the url on button click using the following code.There were no error but the required url is not sroeing in my column field (i used ntext data tpe for this).Please help me if there was some mistake in my code
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void Storetxt(String txt)
{
//connection to the database
string connection = "Data Source=.\\sqlexpress2005;Initial Catalog=PtsKuratlas;Integrated Security=True";
SqlConnection conn = new SqlConnection(connection);
//dataset object to store and manipulating data
DataSet myDataSet = new DataSet();
//data adapters to execute SQL
SqlDataAdapter myDataAdapter = new SqlDataAdapter("SELECT * FROM gti_analytics", conn);
myDataAdapter.Fill(myDataSet, "gti_analytics");
myDataAdapter.InsertCommand = new SqlCommand("INSERT INTO gti_analytics [links] VALUES [txt]");
}
protected void Button1_Click(object sender, EventArgs e)
{
String text = "http://google.com";
Storetxt(text);
}
}
The problem is that you're not actually executing the command against the database. You're defining the InsertCommand to use, but it's not being executed.
Based on that code, I don't see that you need to use a DataAdapter/DataSet anyway, just use an SqlCommand to do the insert, which is more lightweight. Something like this:
public void Storetxt(String txt)
{
//connection to the database
string connection = "Data Source=.\\sqlexpress2005;Initial Catalog=PtsKuratlas;Integrated Security=True";
SqlConnection conn = null;
SqlCommand cmd = null;
try
{
conn = new SqlConnection(connection);
cmd = new SqlCommand("INSERT INTO gti_analytics (Links) VALUES (#Link)", conn);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Link", txt);
conn.Open();
cmd.ExecuteNonQuery();
}
catch{//handle exceptions}
finally
{
if (cmd != null) cmd.Dispose();
if (conn != null)
{
if (conn.State == ConnectionState.Open) conn.Close();
conn.Dispose();
}
}
}
I'd also recommend not using ntext for this in your db. If you really need unicode support, use nvarchar which can go up to 4000 chars pre-sql 2005, or nvarchar(max) which can store as much as ntext from SQL 2005 onwards. If you don't need unicode support, use varchar instead (8000 chars pre-sql 2005, VARCHAR(MAX) from SQL 2005 onwards allows same as text)
shouldn't you be calling myDataAdapter.Update() at the end of the Storetxt method?
oh and i think using ntext for this is overkill.
Your txt method argument is not actually used anywhere in your method which is one reason why it's not being stored in the db.
You don't need a SqlDataAdapter or a DataSet for this operation, as AdaTheDev said. Follow the sample code, although it needs quite a bit of cleaning up.
Also, there's a protocol limit on the number of characters/bytes in the URL, nvarchar should have enough maximum capacity, so you should need neither nvarchar(max) nor (pre-SQL Server 2005) ntext.