So I created and invoked a WCF service in C#, but keep getting a false back, I am unsure as to why it is. It might be to do with the connection string but changing it from the current just gives me errors.
Here's my code:
//Create the new connection
SqlConnection myConnection = new SqlConnection();
//Create the query
String myQuery = "INSERT INTO Player (registrationID, firstName, lastName, phoneNumber, Address, dateOfBirth) " +
" VALUES ('" + registrationID + "', '" + firstName + "', '" + lastName + "', '" + phoneNumber + "', '" + Address + "', '" + dateOfBirth + "');";
//The connectionString can be found in the properties table of the database
myConnection.ConnectionString = "Data Source=C:/Users/User/Documents/Visual Studio 2012/Projects/ADO_LINQ/ADO_LINQ/App_Data/MyDatabase.sdf";
//Initialuze the command
SqlCommand myCommand = new SqlCommand(myQuery, myConnection);
SqlDataReader myReader;
//Run the command
try
{
myConnection.Open();
myReader = myCommand.ExecuteReader();
//Return true if it was successful
return true;
}
catch (Exception ex)
{
return false;
}
As Soner pointed out, your code is susceptible to SQL Injection attacks, and this can be remedied by using parameterized queries. Also, best practice is to use a using block with the connection so it is properly closed and disposed of once the code in the using block is exited (currently you're not even closing the connection when you're done).
Also, ExecuteNonQuery is sufficient for this - it will run the command and then return the number of rows affected (which should be 1 in this case). You can check the number of rows affected and use that to determine success/failure, in addition to using a catch block in the case of an exception. Realistically I would not expect anything other than the value of 1 unless an exception was thrown while executing the command.
Finally your posted code is swallowing the exception. You should do something with the exception (log it, execute some other code, rethrow it - depending on the requirements of your app) rather than simply returning false.
Putting it all together:
using (SqlConnection myConnection = new SqlConnection())
{
// Create the query
String myQuery = "INSERT INTO Player (registrationID, firstName, lastName, phoneNumber, Address, dateOfBirth) " +
" VALUES (#RegistrationID, #FirstName, #LastName, #PhoneNumber, #Address, #DateOfBirth)";
//The connectionString can be found in the properties table of the database
myConnection.ConnectionString = "Data Source=C:/Users/User/Documents/Visual Studio 2012/Projects/ADO_LINQ/ADO_LINQ/App_Data/MyDatabase.sdf";
//Initialuze the command
SqlCommand myCommand = new SqlCommand(myQuery, myConnection);
myCommand.CommandType = CommandType.Text;
// Here you add the values for the parameters in the query
myCommand.Parameters.Add("#RegistrationID", SqlDbType.VarChar).Value = registrationID;
myCommand.Parameters.Add("#FirstName", SqlDbType.VarChar).Value = firstName;
myCommand.Parameters.Add("#LastName", SqlDbType.VarChar).Value = lastName;
myCommand.Parameters.Add("#PhoneNumber", SqlDbType.VarChar).Value = phoneNumber;
myCommand.Parameters.Add("#Address", SqlDbType.VarChar).Value = address;
myCommand.Parameters.Add("#DateOfBirth", SqlDbType.VarChar).Value = dateOfBirth;
//Run the command
try
{
myConnection.Open();
int rowsAffected = myCommand.ExecuteNonQuery();
if (rowsAffected == 1)
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
// Do something with the exception, like logging it so you can review the error
return false;
}
}
The above code wraps the call in a using statement. When the command is created, the parameters are added to the SqlCommand.Parameters collection, and then ExecuteNonQuery is returned. If the result is 1, true is returned, otherwise false is returned. If an error is encountered, false is returned but again you should do something with the exception so you can troubleshoot if needed.
Related
executenonquery() error c#
this is how my code looks like
con.Open();
String name = textBox1.Text.ToString();
String address = textBox2.Text.ToString();
String id = textBox3.Text.ToString();
int iid = Int32.Parse(id);
String semester = textBox4.Text.ToString();
int i_sem = Int32.Parse(semester);
String field = comboBox1.SelectedItem.ToString();
String qry = "insert into Table values('" + name + "','" + address + "'," + iid + "," + i_sem + ",'" + field + "',)";
SqlCommand cmd = new SqlCommand(qry, con);
cmd.ExecuteNonQuery();
executenonquery() always makes me problem !
int i = cmd.ExecuteNonQuery();
You need to fix a couple of things:
Remove the last , in your query.
I don't know if you have a table named Table in your database but you should check if the name is correct.
When you don't know how to correct your code it's better use the try-catch statement to understand where the real problem is in your code. Here is an example about how to handle SQL exception in C# code.
You are getting SqlException because your query syntax is wrong but there is another way to add SQL parameters into your query without need to use a string variable. You could use the SqlParameterCollection.AddWithValue(String, Object) method to achieve the same result and avoid SQL Injection:
command.Connection = connection;
command.CommandType = CommandType.Text;
command.CommandText = "INSERT into YourTableName (name, address, id, semester, field) VALUES (#name, #address, #id, #semester, #field)";
command.Parameters.AddWithValue("#name", name);
command.Parameters.AddWithValue("#address", address);
command.Parameters.AddWithValue("#id", iid);
command.Parameters.AddWithValue("#semester", i_sem);
command.Parameters.AddWithValue("#field", field);
try
{
connection.Open();
int recordsAffected = command.ExecuteNonQuery();
}
catch(SqlException)
{
// error here
}
finally
{
connection.Close(); //close your connection if you do not need to keep it open
}
More info:
AddWithValue Method
SQL Injection
Other examples related to this topic
What i want is to insert all of the data in all rows and columns from my datagrid view into my database. I am not getting any error but this is not working not inserting any value in my database.
con.Open();
SqlCommand cmd = new SqlCommand();
cmd = con.CreateCommand();
for (int i = 0; i < dgEdit.Rows.Count; i++)
{
DateTime ds = DateTime.Now;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO Tb BL_Attendance(Course, Subject,
Year, Section, Name, Room, SeatNo, Status, Date) VALUES('" +
dgvAtt.Rows[i].Cells[0].Value + "', '" +
dgvAtt.Rows[i].Cells[1].Value + "', '" +
dgvAtt.Rows[i].Cells[2].Value + "', '" +
dgvAtt.Rows[i].Cells[3].Value + "', '" +
dgvAtt.Rows[i].Cells[4].Value + "', '" +
dgvAtt.Rows[i].Cells[5].Value + "', '" +
dgvAtt.Rows[i].Cells[6].Value + "', '" +
dgvAtt.Rows[i].Cells[7].Value + "', #Date) ";
cmd.Parameters.AddWithValue("#Date", ds);
cmd.ExecuteNonQuery();
}
MessageBox.Show("Updated! please check the report", "Save",
MessageBoxButtons.OK, MessageBoxIcon.Information);
con.Close();
I was expecting this to insert all of my datagrid values into a table
The logic below tries to be as close as possible to your implementation, but taking into account best practices when dealing with database connections:
// You will need the following namespaces:
// using System;
// using System.Data;
// using System.Data.SqlClient;
// using System.Windows.Forms;
var connectionString = "Your SQL Server connection string";
using (var con = new SqlConnection(connectionString))
{
con.Open();
var cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText =
"INSERT INTO Tbl_Attendance (Course, Subject, Year, Section, Name, Room, SeatNo, Status, Date) " +
"VALUES (#Course, #Subject, #Year, #Section, #Name, #Room, #SeatNo, #Status, #Date)";
var courseParam = cmd.Parameters.Add("#Course", SqlDbType.VarChar, 50);
var subjectParam = cmd.Parameters.Add("#Subject", SqlDbType.VarChar, 50);
var yearParam = cmd.Parameters.Add("#Year", SqlDbType.VarChar, 50);
var sectionParam = cmd.Parameters.Add("#Section", SqlDbType.VarChar, 50);
var nameParam = cmd.Parameters.Add("#Name", SqlDbType.VarChar, 50);
var roomParam = cmd.Parameters.Add("#Room", SqlDbType.VarChar, 50);
var seatNoParam = cmd.Parameters.Add("#SeatNo", SqlDbType.VarChar, 50);
var statusParam = cmd.Parameters.Add("#Status", SqlDbType.VarChar, 50);
var dateParam = cmd.Parameters.Add("#Date", SqlDbType.DateTime);
dateParam.Value = DateTime.Now;
// If you are going to insert a lot of records, it's advised to call the Prepare method on your SqlCommand.
// Un-comment the line below if you want to see how this behaves.
// cmd.Prepare();
foreach (DataGridViewRow row in dgEdit.Rows)
{
courseParam.Value = row.Cells[0].Value;
subjectParam.Value = row.Cells[1].Value;
yearParam.Value = row.Cells[2].Value;
sectionParam.Value = row.Cells[3].Value;
nameParam.Value = row.Cells[4].Value;
roomParam.Value = row.Cells[5].Value;
seatNoParam.Value = row.Cells[6].Value;
statusParam.Value = row.Cells[7].Value;
cmd.ExecuteNonQuery();
}
}
MessageBox.Show("Updated! please check the report", "Save", MessageBoxButtons.OK, MessageBoxIcon.Information);
Reason behind the changes:
When possible, instantiate and open your SqlConnection connection inside a
using statement. This will ensure that your connection is always
closed (disposed) when you are done with it in the scope.
Always use parameters in your queries when interacting with any external input, to avoid Bobby's mom exploit! (https://xkcd.com/327/).
This will ensure that your code is not susceptible to SQL injection.
As you can see, I added some parameters, but because you didn't
provide your table schema I made then VARCHAR(50) with the
exception of the #Date one where it's clear that you are saving a
System.DateTime. Please feel free to change the SqlDbType.VarChar
to the correct type where needed.
I moved the call to MessageBox.Show outside the using scope so it doesn't interfere with the connection disposal.
Another enhancement that you could do to this logic is implementing the use of the System.Transactions.TransactionScope class (you must add a reference to System.Transactions.dll), to ensure that if there's an error during any of the inserts, nothing gets committed to the database.
Your prototype is correct but you did one mistake, dgvAtt.Rows[i].Cells[0].Value return an Object to must convert it to ToString() or the column data in your table that could match with.
Let's say this is my form
I Created a table 'Person'
Code Source
private void button1_Click(object sender, EventArgs e)
{
try
{
SqlCommand cmd = new SqlCommand();
cmd = con.CreateCommand();
for (int i = 0; i < dgvAtt.Rows.Count - 1; i++)
{
con.Open();
cmd.CommandType = CommandType.Text;
string Query = "INSERT INTO Person (idPerson, fullnamePerson) VALUES (" + dgvAtt.Rows[i].Cells[0].Value.ToString() + ",'" + dgvAtt.Rows[i].Cells[1].Value.ToString() + "')";
cmd.CommandText = Query;
cmd.ExecuteNonQuery();
con.Close();
}
MessageBox.Show("Updated! please check the report", "Save", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Don't write any Parameters because this will give you an exception.
I am using c# and I cannot get any vaue. The data returns null. This is my code.
SQLiteConnection DBConnection;
DBConnection = GetMyconnection();
DBConnection.Open();
string DBCommand = "SELECT * FROM settings WHERE setting_key = '" + setting_key + "' LIMIT 1";
using (SQLiteCommand sqlCommand = new SQLiteCommand(DBCommand, DBConnection))
{
using (SQLiteDataReader DBDataReader = sqlCommand.ExecuteReader())
{
if (DBDataReader.Read())
{
object data = sqlCommand.ExecuteScalar();
return DBDataReader.GetString(DBDataReader.GetOrdinal("setting_value"));
}
else
{
return "Error";
}
}
}
DBConnection.Close();
This code is placed in a global helper function which I call from a form.
Kindly help.
The main item is saw was that you were running an ExecuteScalar on the same command as the ExecuteReader and I could see no reason why. Other things I noted was that you were concatenating the statement instead of using parameters, you only needed one value but were using SELECT *, and there was no exception handling. I would have a Unique Index on the settingkey column to speed up the query and prevent duplicates, so you don't need to have the LIMIT 1 on the command
I rolled this up trying to use as much of your code as possible. I altered the SQL command to get the one value that you wanted, only using the ExecuteScalar method, and using the conditional operator instead of the if...then block. The actual command has been wrapped in a try...catch for exception handling and will provide error feedback
string ReturnValue;
SQLiteConnection DBConnection;
DBConnection = GetMyconnection();
DBConnection.Open();
string DBCommand = "SELECT setting_value FROM settings WHERE setting_key = #settingkey LIMIT 1";
using (SQLiteCommand sqlCommand = new SQLiteCommand(DBCommand, DBConnection)) {
sqlCommand.parameters.AddWithValue("#settingkey", setting_key);
try {
object data = sqlCommand.ExecuteScalar();
ReturnValue = (data != null) ? data.ToString() : "Error";
}
catch (Exception ex) { ReturnValue = "Exception: " + ex.Message; }
}
DBConnection.Close();
return ReturnValue;
this code read a list of row but if your query is ok work.
string sql = "SELECT * FROM settings WHERE setting_key = '" + setting_key + "' LIMIT 1";
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
SQLiteDataReader reader = command.ExecuteReader();
while (reader.Read())
Console.WriteLine("Name: " + reader["setting_value"] + "\tScore: " + reader["score"]);
While making a software monitoring system in C#, during our testing we encountered a problem with the database connections.
Even if we have declared multiple connections, the programs always throw an exception:
"Current state connection is opening.:"
Why is that?
Is it not possible to have two connections accessing the same database at the same time?
We are using Access Database.
private void UpdateListView(string query)
{
command.Connection = connection;
insertinto = "1";
command.CommandText = "Update ReaderUHF Set Identification = '" + insertinto + "' where EPC = '" + query + "'";
connection.Open();
command.ExecuteNonQuery();
connection.Close();
showdata(insertinto);
}
//After 3 seconds. This thread is performed while the main thread is running
private void FinalLocation()
{
command_1.Connection = connection_1;
finaLoc = "Outside";
command_1.CommandText = "Update ReaderUHF Set Location = '" + insertinto + "' where EPC = '" + query + "'";
connection_1.Open();
command_1.ExecuteNonQuery();
connection_1.Close();
}
It throws an exception of "Current connection state is opening".
You need to only share the connection string between the two threads. Though it has been a long time since I have seen Access used. Can you switch to Sqlite? if it is possible you should do it this way.
It is normally never a good idea to embed SQL code like this into a program but it sounds like this is just a school project so I would change the code to below. Just know in the real world you should do this but should add some Data Access layer like nHibernate or Entity Framework.
private void UpdateLocation(string newLocation, string query, string connectionString)
{
//Using using statements calls close as well as dispose
using(OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
using (OleDbCommand comm = new OleDbCommand())
{
comm.Connection = conn;
comm.CommandText = "Update ReaderUHF Set Location = #location where EPC = #query";
//Always use Parameters to avoid SQL injection
comm.Parameters.AddWithValue("#location", newLocation);
comm.Parameters.AddWithValue("#query", query);
comm.ExecuteNonQuery();
}
}
}
private void UpdateIdentification(string identification, string query, string connectionString)
{
using(OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
using (OleDbCommand comm = new OleDbCommand())
{
comm.Connection = conn;
comm.CommandText = "Update ReaderUHF Set Identification = #identification where EPC = #query";
comm.Parameters.AddWithValue("#identification", identification);
comm.Parameters.AddWithValue("#query", query);
comm.ExecuteNonQuery();
}
}
}
If the above code doesn't work you might have to use a lock to get around multiple connections. Something like this:
private object lockObj = new object();
private void UpdateListView(string query)
{
command.Connection = connection;
insertinto = "1";
command.CommandText = "Update ReaderUHF Set Identification = '" + insertinto + "' where EPC = '" + query + "'";
lock(lockObj)
{
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
showdata(insertinto);
}
//After 3 seconds. This thread is performed while the main thread is running
private void FinalLocation()
{
command_1.Connection = connection_1;
finaLoc = "Outside";
command_1.CommandText = "Update ReaderUHF Set Location = '" + insertinto + "' where EPC = '" + query + "'";
lock(lockObj)
{
connection_1.Open();
command_1.ExecuteNonQuery();
connection_1.Close();
}
}
Whenever a user calls Open on a connection, the pooler looks for an
available connection in the pool. If a pooled connection is available,
it returns it to the caller instead of opening a new connection. When
the application calls Close on the connection, the pooler returns it
to the pooled set of active connections instead of closing it. Once
the connection is returned to the pool, it is ready to be reused on
the next Open call.
http://msdn.microsoft.com/en-us/library/8xx3tyca%28v=vs.110%29.aspx
I am working on a project for a class. One of the requirements is that my program pulls information from a few textboxes on a web form and stores the values into a database. I have pulled information out of a database and figured putting stuff into one would be roughly the same process. When I tried however I get no errors, but when I open the database up there is nothing there either.
Code:
OleDbConnection con;
OleDbCommand com;
con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + #"C:\Users\D40010490\Desktop\GMDatabase.accdb");
com = con.CreateCommand();
try
{
con.Open();
lblError.Text = "Successfully Connected to Database";
String firstName = txtFirstName.Text;
String lastName = txtLastName.Text;
String email = txtEmail.Text;
String password = txtPassword.Text;
String cpassword = txtCPassword.Text;
String Description = txtDesc.Text;
com.CommandText = "INSERT INTO Users "
+ "(lastname, firstname, email, password) "
+ "VALUES (" + "'" +lastName+"'"
+ "'" + firstName +"'"+ "'"+email+"'"+ "'"+password+"');";
con.Close();
}
catch (Exception ex)
{
lblError.Text = ex.ToString();
}
please advise.
You never actually execute the command:
com.CommandText = "INSERT INTO Users "...
com.ExecuteNonQuery();
con.Close();
You should also get in the habit of using parameters instead of concatenating SQL (especially when dealing with users and passwords).
You need to call com.ExecuteNonQuery() in order to run the command.
Mark Cidade have reason , always you want insert in database you should execute the retrieve, check very good your code and bug if is necesary for resolve...