C# Sql Command for Insering into a database - c#

I am new to Visual C# programming language and recently i was trying to make a application that is supposed to insert into a local database of users some data but every times my code runs and the insertion works fine the database does not update.This is the code that i am using
try
{
cn.Open();
SqlCommand insert = new SqlCommand();
insert.CommandText = "insert into Clienti (Nume,Prenume,Parola,Email) values(#Nume,#Prenume,#Parola,#Email)";
insert.Connection = cn;
insert.Parameters.AddWithValue("#Nume", register_nume.Text);
insert.Parameters.AddWithValue("#Prenume", register_prenume.Text);
insert.Parameters.AddWithValue("#Parola", register_password.Text);
insert.Parameters.AddWithValue("#Email", register_email.Text);
insert.ExecuteNonQuery();
SqlDataReader reader = insert.ExecuteReader();
while (reader.Read()) { }
MessageBox.Show("Added succesfully");
}
catch (Exception ex)
{
MessageBox.Show(""+ex);
}
I already tried the property Copy to output and it doesn't seems to work.
I am sorry for any grammar mistakes that i made,I would be grateful for any help.

insert.ExecuteNonQuery();
SqlDataReader reader = insert.ExecuteReader();
while (reader.Read()) { }
You only need the ExecuteNonQuery, it will run the INSERT. You need to use ExecuteReader instead only when you're running a statement that produces result sets (eg. SELECT). So it should be:
insert.ExecuteNonQuery();

Its because you have to now read the database using a select statement, you cant use an INSERT SQL statement to read.
You could add the following immediately after your insert.
using(var selectCmd = new SqlCommand("SELECT Nume,Prenume,Parola,Email FROM Clienti WHERE Nume = #Nume", cn))
{
selectCmd.Parameters.AddWithValue("#Nume", register_nume.Text);
using(SqlDataReader reader = selectCmd.ExecuteReader())
{
while (reader.Read()) { }
}
}
That said if you want to know IF the row was inserted or how many records were inserted ExecuteNonQuery returns the number of rows affected. You could change that part of the code like this:
var recordsAffected = insert.ExecuteNonQuery();
if(recordsAffected > 0)
MessageBox.Show("Added succesfully");
else
MessageBox.Show("Nothing happened");
Although in this particular case it would not make sense because if nothing was inserted it would probably be caused by an Exception.
Some side notes
Always wrap types that implement IDisposable in using blocks (see code above as example). It ensures that resources are always released as soon as you are done with them even if an Exception is thrown.
Never swallow Exceptions! Either recover from one and log it or do not catch it at all. If you swallow it you will never know if/why your code broke.

This part of your code is preparing the SQL command that you are running
cn.Open();
SqlCommand insert = new SqlCommand();
insert.CommandText = "insert into Clienti (Nume,Prenume,Parola,Email) values(#Nume,#Prenume,#Parola,#Email)";
insert.Connection = cn;
insert.Parameters.AddWithValue("#Nume", register_nume.Text);
insert.Parameters.AddWithValue("#Prenume", register_prenume.Text);
insert.Parameters.AddWithValue("#Parola", register_password.Text);
insert.Parameters.AddWithValue("#Email", register_email.Text);
The SQL command that your code is running, is an INSERT statement, which only adds a new record to your table.
This statement runs the command that you setup earlier:
insert.ExecuteNonQuery();
If I understand correctly, here you are trying to read the data from the table again:
SqlDataReader reader = insert.ExecuteReader();
while (reader.Read()) { }
Problem is, your command is NOT set for reading. To read data, you need to use a SELECT statement. Something like this:
insert.CommandText = "SELECT Nume,Prenume,Parola,Email from Clienti" ;
So, to read the data after executing the insert, you should do this:
insert.CommandText = "SELECT Nume,Prenume,Parola,Email from Clienti" ;
SqlDataReader reader = insert.ExecuteReader();
while (reader.Read()) { }

You ar executing 2 times the query:
insert.ExecuteNonQuery();
SqlDataReader reader = insert.ExecuteReader();
Try to get the affected rows
int rows = insert.ExecuteNonQuery();
I would suggest creating a stored procedure in your database and just execute the SP.
It's always better to execute SP from code and leave the SQL programming in the DB.

Related

changes to db from csharp are partly commited

so as title says, I have a .net program that has a method( names dont matter )..
so theres a method where I loop through a datatable and fill it with data from csv, then i build a query where I add the parameters and do
insert into bakashot id,name,bla values(:id,:name,:bla);
and I build the parameters like this for example
cmd.Parameters[":id"].Value = id;
Anyways, all good, database table is filled with values.
Now, I have another table lets say bakashot_history, I want before that insert statement to the bakashot table, to take the records from original bakashot, insert them to the bakashot_history table, and then clean the records from the bakashot table.
I've noticed that it will only commit if I put a debug on, otherwise theres no exception or anything -it just wont commit.
so Im thinking like, if the insert statement went well without any need of debug or thread.sleep(which I tried aswell) , why do the DELETE statement and the "Transfer"(insert into a from b) suddenly needs the debug? thats wierd and im clueless..
any help will be appreciated!
nobody replied to my post,but eitherway the solution was wrapping everything with oracle transaction
using (OracleTransaction tran = myConnection.BeginTransaction())
{
StringBuilder sql = new StringBuilder("INSERT INTO Bakashot_Mll_TOCharge
(ID)" + "VALUES (:ID");
using (OracleCommand cmd = new OracleCommand(sql.ToString(), myConnection))
{
cmd.Transaction = tran;
AddTableParameters(cmd);
foreach (DataRow row in dt.Rows)
{
cmd.Parameters[":ID"].Value = row[0];
cmd.ExecuteNonQuery();
}
}
-----//this is the part that didnt work unless the debug mode was on\\------
using (OracleCommand com = new
OracleCommand("Store_And_Delete", myConnection))
{
com.Transaction = tran;
com.CommandType = CommandType.StoredProcedure;
com.ExecuteNonQuery();
}
tran.Commit();
myConnection.Close();
}

How to override "duplicate entry warning" when run an append query (Access db, from c# asp.net)?

I have a query in the access database that appends email addresses from one table to another. In the source table there may be many duplicated emails. In the target table the email field is unique. Before running the query, there may already in the target table emails that are in the source table.
When running the query manually, I get a message about duplicates and I have to click on Yes to run the query anyway.
But when I try to run the query from the asp.net, c#, I get an exception and nothing is done.
How can I override the exception? I mean, how can I "tell" the system to assume I clicked on Yes after the warning?
Here is my code:
public static void RunQuery(string db, string command)
{
OleDbConnection conn = getConn(db); //set the value for conn
try
{
if (conn != null) conn.Close();
conn.Open();
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = command; // query name
cmd.ExecuteNonQuery();
conn.Close();
}
catch (Exception e)
{
log.Error(e);
throw;
}
finally
{
if (conn != null)
conn.Close();
}
}
Thanks
It has never been clear when/how the error msg of duplicates will trigger.
I find that this (in most cases) will run the append query, and errors are ignored.
This:
// run append query
using (OleDbConnection conn =
new OleDbConnection(Properties.Settings.Default.AccessDB))
{
using (OleDbCommand cmdSQL =
new OleDbCommand("AddToHotelss", conn))
{
conn.Open();
cmdSQL.CommandType = CommandType.StoredProcedure;
cmdSQL.ExecuteNonQuery();
}
}
Now, the above runs this saved query in Access:
INSERT INTO tblHotels2 ( FirstName, LastName, HotelName, EmailName )
SELECT tblHotels.FirstName, tblHotels.LastName, tblHotels.HotelName,
tblHotels.EmailName
FROM tblHotels
WHERE (tblHotels.City = "Edmonton");
And I have a unique index on EmailName - and the above works.
So, give the "setting" of CommandType = StoredProcedure.
The above SHOULD work.
If it does not?
Then you have to consider introduction of the office.interop ACE data engine. (I don't think that's a good idea).
Or, if above idea does not work?
You have to modify your query to prevent duplicates in the first place..
The query then becomes this:
INSERT INTO tblHotels2 ( FirstName, LastName, HotelName, EmailName )
SELECT tblHotels.FirstName, tblHotels.LastName, tblHotels.HotelName,
tblHotels.EmailName
FROM tblHotels
WHERE (tblHotels.City="Edmonton")
AND
(tblHotels.EmailName NOT IN (SELECT EmailName from tblHotels2.EmailName));
So, as suggested, you re-write the query to never allow duplicates.
I would however give the commandText setting (StoredProcedure) as per above - since in the past I had that work for me. (the duplicates message did not trigger, or stop the append).

Fetch data from MySql to C# application

I have a MySql table from which I fetch data to my C# application. Randomly some data are inserted in this table form another source. I want to fetch those data continuously in my C# application. My DB connection and select query are following :
string connection = "Server=localhost;Database=intel;Uid=root;Pwd=";
MySqlConnection dbcon = new MySqlConnection(connection);
MySqlCommand selectData;
dbcon.Open();
selectData = dbcon.CreateCommand();
selectData.CommandText = "SELECT user_id, user_name,user_type FROM win_user ORDER BY user_id ASC ";
MySqlDataReader rdr = selectData.ExecuteReader();
I want to execute my select query unit it get any data.
if
Get data = null
execute my select query again
else
Get data = data
execute my next code
I think it can be happen with while loop, but I dont know how ? Can any onk help me ?
What you want to do sounds odd but, to answer the question as asked, you can use a loop like so:
MySqlDataReader rdr = selectData.ExecuteReader();
// Check whether the result set is empty.
while (!rdr.HasRows)
{
rdr.Close();
// Pause before trying again if appropriate.
rdr = selectData.ExecuteReader();
}
while (rdr.Read())
{
// Read data here.
}
use this
If(rdr.HasRows)
{
rdr.Read();
// do your logic
}
rdr.Close();
use rdr.Read() only when you have some data in datareader object.
if you simply want to read values without checking null than use this
while (rdr.Read())
{
// do logic
}
rdr.Close();
this loop runs as many times as no of rows exist in your select query result.

How to check if a row is present in SQL Server table or not?

I am trying to check if there is a row present in a SQL Server table or not.
If the row exists (on a particular TicketID), it should show a messagebox that you can't continue further as there is already an entry in database. But if there isn't, it should insert some records (on that particular TicketID).
I tried try and catch but wasn't able to do it :
Here is the code of query: (hardcoded ticketID for example)
bool no;
try
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ST"].ConnectionString.ToString());
con.Open();
cmd.CommandText = "SELECT EngineerVisited from tblTicketTechnical where TicketID=1";
cmd.Connection = con;
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
bool = rdr.GetBoolean(0);
}
con.Close();
}
catch
{
MessageBox.Show("Cannot continue");
}
I would really appreciate if someone could suggest a function that will return true if row is found and return false, if it isn't.
You should follow the same logic in code as the logic you state in English: if there's already a ticket show a message and if not, insert some data.
var checkQuery = "SELECT COUNT(*) FROM tblTicketTechnical where TicketID=1";
var command = new OleDbCommand(checkQuery, con);
con.Open();
int count = (int)command.ExecuteScalar();
if(count > 0)
{
//Already exists, show message
}
else
{
var insertQuery = "INSERT INTO tblTicketTechnical(col1, col2) VALUES('val1', val2')";
con = new OleDbCommand(insertQuery, con);
con.ExecuteNonQuery();
}
Please mind that this is written out of my head and not tested. Nor have I implemented exception handling. This is just to show the logic how you can perform what you want to achieve.
You can use HasRows property of SQLDataReader.
A catch block will only be executed if your code throws an exception. Here it is simply not happening.
Instead of Try/Catch use if statements and checks on your query results.
Create procedure and code like this
IF NOT EXISTS (SELECT 1 FROM youtable WHERE id= #id)
BEGIN
RAISERROR ('Record Exists', 16, 2)
END
ELSE
Begin
INSERT INTO YOURTABEL(COLUM1,COLUM2) VALUES(VALUE1, VALUE2)
END
and then by try catch you can show message to user
You can use DataTableReader.HasRows Property
The HasRows property returns information about the current result set

What am I doing wrong with this query?

I can't seem to find why this function doesn't insert records into the database. :(
I get no error messages or whatsoever, just nothing in the database.
EDIT: this is how my query looks now .. still nothing ..
connection.Open();
XmlNodeList nodeItem = rssDoc.SelectNodes("/edno23/posts/post");
foreach (XmlNode xn in nodeItem)
{
cmd.Parameters.Clear();
msgText = xn["message"].InnerText;
C = xn["user_from"].InnerText;
avatar = xn["user_from_avatar"].InnerText;
string endhash = GetMd5Sum(msgText.ToString());
cmd.Parameters.Add("#endhash",endhash);
cmd.CommandText = "Select * FROM posts Where hash=#endhash";
SqlCeDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string msgs = reader["hash"].ToString();
if (msgs != endhash || msgs == null)
{
sql = "INSERT INTO posts([user],msg,avatar,[date],hash) VALUES(#username,#messige,#userpic,#thedate,#hash)";
cmd.CommandText = sql;
cmd.Parameters.Add("#username", C);
cmd.Parameters.Add("#messige", msgText.ToString());
cmd.Parameters.Add("#userpic", avatar.ToString());
cmd.Parameters.Add("#thedate", dt);
cmd.Parameters.Add("#hash", endhash);
cmd.ExecuteNonQuery();// executes query
adapter.Update(data);// saves the changes
}
}
reader.Close();
}
connection.Close();
Does nodeItem actually have any items in it? If not, the contents of the foreach loop aren't being executed.
What's the adapter and data being used for? The queries and updates seem be done via other commands and readers.
What does 'hash' actually contain? If it's a hash, why are you hashing the content of the hash inside the while loop? If not, why is it being compared against a hash in the query SELECT * FROM posts WHERE hash = #endhash?
Won't closing the connection before the end of the while loop invalidate the reader used to control the loop?
Lots of things going on here...
You are using the command 'cmd' to loop over records with a datareader, and then using the same 'cmd' command inside the while statement to execute an insert statement. You declared another command 'cmdAdd' before but don't seem to use it anywhere; is that what you intended to use for the insert statement?
You also close your data connection inside the while loop that iterates over your datareader. You are only going to read one record and then close the connection to your database that way; if your conditional for inserting is not met, you're not going to write anything to the database.
EDIT:
You really should open and close the connection to the database outside the foreach on the xmlnodes. If you have 10 nodes to loop over, the db connection is going to be opened and closed 10 times (well, connection pooling will probably prevent that, but still...)
You are also loading the entire 'posts' table into a dataset for seemingly no reason. You're not changing any of the values in the dataset yet you are calling an update on it repeatedly (at "save teh shanges"). If the 'posts' table is even remotely large, this is going to suck a lot of memory for no reason (on a handheld device, no less).
Is anything returned from "Select * FROM posts Where hash=#endhash"?
If not, nothing inside the while loop matters....
Why are you closing the Database Connection inside the while loop?
The code you posted should throw an exception when you try to call cmd.ExecuteNonQuery() with an unopen DB connection object.
SqlCeCommand.ExecuteNonQuery() method returns the number of rows affected.
Why don't you check whether it is returning 1 or not in the debugger as shown below?
int rowsAffectedCount = cmd.ExecuteNonQuery();
Hope it helps :-)
You've got some issues with not implementing "using" blocks. I've added some to your inner code below. The blocks for the connection and select command are more wishful thinking on my part. I hope you're doing the same with the data adapter.
using (var connection = new SqlCeConnection(connectionString))
{
connection.Open();
var nodeItem = rssDoc.SelectNodes("/edno23/posts/post");
foreach (XmlNode xn in nodeItem)
{
using (
var selectCommand =
new SqlCeCommand(
"Select * FROM posts Where hash=#endhash",
connection))
{
var msgText = xn["message"].InnerText;
var c = xn["user_from"].InnerText;
var avatar = xn["user_from_avatar"].InnerText;
var endhash = GetMd5Sum(msgText);
selectCommand.Parameters.Add("#endhash", endhash);
selectCommand.CommandText =
"Select * FROM posts Where hash=#endhash";
using (var reader = selectCommand.ExecuteReader())
{
while (reader.Read())
{
var msgs = reader["hash"].ToString();
if (msgs == endhash && msgs != null)
{
continue;
}
const string COMMAND_TEXT =
"INSERT INTO posts([user],msg,avatar,[date],hash) VALUES(#username,#messige,#userpic,#thedate,#hash)";
using (
var insertCommand =
new SqlCeCommand(
COMMAND_TEXT, connection))
{
insertCommand.Parameters.Add("#username", c);
insertCommand.Parameters.Add(
"#messige", msgText);
insertCommand.Parameters.Add(
"#userpic", avatar);
insertCommand.Parameters.Add("#thedate", dt);
insertCommand.Parameters.Add(
"#hash", endhash);
insertCommand.ExecuteNonQuery();
// executes query
}
adapter.Update(data); // saves teh changes
}
reader.Close();
}
}
}
connection.Close();
}
Of course with the additional nesting, parts should be broken out as separate methods.
I suspect your problem is that you're trying to reuse the same SqlCeCommand instances.
Try making a new SqlCeCommand within the while loop. Also, you can use the using statement to close your data objects.
Why are you calling adapter.Update(data) since you're not changing the DataSet at all? I suspect you want to call adapter.Fill(data). The Update method will save any changes in the DataSet to the database.
How to debug programs: http://www.drpaulcarter.com/cs/debug.php
Seriously, can you post some more information about where it's working? Does it work if you use SQL Server Express instead of SQL CE? If so, can you break out SQL Profiler and take a look at the SQL commands being executed?

Categories