Connection state is opened but not valid? - c#

I have this code that I use for copy one table to another, but I got error while executing command statement.
Error says that connection is not open or valid. When I debug I can see it is opened.
Really don't know why is not valid.
con.ConnectionString = ConfigurationManager.ConnectionStrings["Con2"].ConnectionString;
con.Open();
cmd = new MySqlCommand("SELECT COUNT(*) FROM " + ConfigSettings.ReadSetting("main_base"), con);
int nRows = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
if (nRows > 0)
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["Con1"].ConnectionString;
con.Open();
cmd = new MySqlCommand("INSERT INTO temp_data SELECT * FROM data");
cmd.ExecuteScalar();
}
Everything goes well until last command:
cmd = new MySqlCommand("INSERT INTO temp_data SELECT * FROM data");
cmd.ExecuteScalar();
Is this even possible if these two database are on different servers? Maybe I need to have two connections opened at the same time or something like that?

Pass the connection object to the MySqlCommand constructor:
cmd = new MySqlCommand("INSERT INTO temp_data SELECT * FROM data", con);

using (var conn = new MySqlConnection(ConfigurationManager.ConnectionStrings["Con2"].ConnectionString))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText ="SELECT COUNT(*) FROM " + ConfigSettings.ReadSetting("main_base");
int nRows = Convert.ToInt32(cmd.ExecuteScalar());
if (nRows > 0)
{
using (var conn2 = new MySqlConnection(ConfigurationManager.ConnectionStrings["Con1"].ConnectionString))
{
conn2.Open();
using (var cmd2 = conn2.CreateCommand())
{
cmd2.CommandText ="INSERT INTO temp_data SELECT * FROM data";
cmd2.ExecuteScalar();
}
}
}
}
}

Related

Checking if username is available in database

I'm trying to check if the username is already in use in C# database and it's giving me this error
SqlConnection cn = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = C:\Users\admin\Desktop\241 Project sem 1 2020-2021\Online Banking - ITIS 241 project group 9\UobBankDatabase.mdf; Integrated Security = True; Connect Timeout = 30");
cn.Open();
SqlCommand cmd = new SqlCommand("select * from LoginTable where user_name='" + textBox1.Text + "'", cn);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
dr.Close();
MessageBox.Show("Username Already exist please try another ", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
dr.Close();
}
and yes I'm a newbie
Use this:
SqlCommand cmd = new SqlCommand("Select count(*) from LoginTable where user_name='" + textBox1.Text + "'", cn);
Then:
var dr = cmd.ExecuteScalar();
if (dr != null)
{
//Exists
}
else
{
//Unique username
}
Google it please:
Since the error is SqlException: Invalid object name 'Movie' , that
means the table named 'Movie' has not created or the Database you are
referring has not created. To see if the Database or table 'Movie' has
created, open SQL Server Object Explorer and check the Database name
is the same as in appsettings. json
And Please tell us at what line do you get that?
Is that this line =>if (dr.Read())
Let's extract method for the check:
private static bool NameAvailable(string name) {
//DONE: wrap IDisposable into using
using (SqlConnection cn = new SqlConnection("Connection String Here")) {
cn.Open();
//DONE: keep Sql readable
//DONE: make Sql parametrize
//DONE: select 1 - we don't want entire record but a fact that record exists
string sql =
#"select 1
form LoginTable
where user_name = #prm_user_name";
using (var cmd = new SqlCommand(sql, cn)) {
cmd.Parameters.Add("#prm_user_name", SqlDbType.VarChar).Value = name;
using (var dr = cmd.ExecuteReader()) {
return !dr.Read(); // Not available if we can read at least one record
}
}
}
}
Then you can put
if (!NameAvailable(textBox1)) {
// Let's be nice and put keyboard focus on the wrong input
if (textBox1.CanFocus)
textBox1.Focus();
MessageBox.Show("Username Already exist please try another ",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
some changes only.it is better to get what is the error than a temporary solution so print your query first and run it in the sqlserver . also add initial catalog instead of attacjing mdf files its way better in my opinion.
<connectionStrings>
<add name="stringname" connectionString="Data Source=mssql;Initial Catalog=databasename; Persist Security Info=True;User ID=sa;Password=*****;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
</connectionStrings>
using a connection string instead also
SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["stringname"].ConnectionString);
cn.Open();
string query = "select * from LoginTable where user_name='" + textBox1.Text.ToString() + "'";
SqlCommand cmd = new SqlCommand(query, cn);
SqlDataReader dr = cmd.ExecuteReader();
//print query if error and comment the execute reader section when printing the query to know the error Respone.Write(query);
if (!dr.HasRows)
{
// ur code to insert InsertItemPosition values
}
else
{
//show username exist
}
dr.Close();
Try this:
string conString = ConfigurationManager.ConnectionStrings["YourConnection"].ConnectionString;
using (SqlConnection con = new SqlConnection(conString))
{
using (SqlCommand cmd = new SqlCommand("SELECT COUNT(UserName) as UserCount FROM LoginTable WHERE user_name = #user_name", con))
{
con.Open();
cmd.Parameters.AddWithValue("#user_name", TextBox1.Text);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
if (dr.HasRows)
{
if(Convert.ToInt32(dr["UserCount"].ToString()) >= 1)
{
// Exists
}
else
{
// Doesn't Exist
}
}
}
con.Close();
}
}

Data type error conversion failed varchar to int

I am storing cookies and trying to show Items in cart with help of cookie but I got this error "Conversion failed when converting the varchar value 'CartPID' to data type int" at sda.Fill(dt) when click on cart button. I Know CartPID is varchar but how can I overcome this error.At index[0]="CartPID" it is holding string value while I need int value which are on the index starting from One.
string CookieData = Request.Cookies["CartPID"].Value.Split('=')[1];
string[] CookieDataArray = CookieData.Split(',');
if (CookieDataArray.Length > 0)
{
h5NoItems.InnerText = "MY CART (" + CookieDataArray.Length + " Items)";//to show total num of items
DataTable dt = new DataTable();
Int64 CartTotal = 0;
Int64 Total = 0;
for (int i = 0; i <= CookieDataArray.Length; i++)//this loop will get PID and sizeID
{
string PID = CookieDataArray[i].ToString().Split('-')[0];
// string SizeID = CookieDataArray[i].ToString().Split('-')[1];
String CS = ConfigurationManager.ConnectionStrings["dbx"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
using (SqlCommand cmd = new SqlCommand("Select * from Products where ID='" + PID+"'", con))
{
cmd.CommandType = CommandType.Text;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
}
}
You should never use input from the client without making sure it's safe. Use a SqlParameter when building this query so you aren't facilitating an SQL injection
var query = "Select * from Products where ID = #id";
using( var command = new SqlCommand(query, con){
command.Parameters.Add("#id", SqlDbType.Varchar).Value = pid;
....
}
If the PID is really an int use something like:
int pid;
if(int.TryParse(CookieDataArray[i].ToString().Split('-')[0], out pid){
// the sql command goes here SqlDbType.Int this time
}
using (SqlCommand cmd = new SqlCommand("Select * from Products where ID=" + PID, con))
{
cmd.CommandType = CommandType.Text;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
}
}
or try
using (SqlCommand cmd = new SqlCommand("Select * from Products where ID=#PID", con))
{
cmd.Parameters.Add("#PID", SqlDbType.Int);
cmd.Parameters["#PID"].Value = PID;
cmd.CommandType = CommandType.Text;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
}
}

How to update records in SQL Server database through asp.net?

I'm writing this code in asp.net but still it's not updating record in a SQL Server database:
SqlCommand cmd4 = new SqlCommand("Select * from roomdetail", conn);
SqlDataReader dr = cmd4.ExecuteReader();
while (dr.Read())
SqlCommand cmd3 = new SqlCommand("update [roomdetail] set [rid]=' " +count+1 + " ' where rid = 0 AND roomtype='"+typeRadioButtonList1.SelectedItem.ToString()+ "' ", conn);
Proper way to use ado.net:
var newId = count + 1;
var roomType = typeRadioButtonList1.SelectedItem.ToString();
using (var connection = new SqlConnection("your db connection string here"))
{
var query = "UPDATE [roomdetail] SET [rid] = #rid WHERE [rid] = 0 AND roomtype = #roomType";
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#rid", newId);
command.Parameters.AddWithValue("#roomType", roomType);
try
{
command.Connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
//handle exception
}
}
You are Missing ExecuteNonQuery Method Write Below code
SqlCommand cmd4 = new SqlCommand("Select * from roomdetail", conn);
SqlDataReader dr = cmd4.ExecuteReader();
while (dr.Read())
SqlCommand cmd3 = new SqlCommand("update [roomdetail] set [rid]=' " +count+1 + " ' where rid = 0 AND roomtype='"+typeRadioButtonList1.SelectedItem.ToString()+ "' ", conn);
cmd3.executeNonQuery();
Assuming the connection is already opened, in your while loop you are missing the following statement:
cmd3.ExecuteNonQuery();
You have to execute the command in order for the database to be updated.

How to run multiple SQL commands in a single SQL connection?

I am creating a project in which I need to run 2-3 SQL commands in a single SQL connection.
Here is the code I have written:
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\project.mdf;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("select * from " + mytags.Text + " ", con);
SqlDataReader rd = cmd.ExecuteReader();
if (rd.Read())
{
con.Close();
con.Open();
SqlCommand cmd1 = new SqlCommand("insert into " + mytags.Text + " values ('fname.lname#gmail.com','" + TextBox3.Text + "','" + TextBox4.Text + "','" + TextBox5.Text + "','"+mytags.Text+"')", con);
cmd1.ExecuteNonQuery();
label.Visible = true;
label.Text = "Date read and inserted";
}
else
{
con.Close();
con.Open();
SqlCommand cmd2 = new SqlCommand("create table " + mytags.Text + " ( session VARCHAR(MAX) , Price int , Description VARCHAR(MAX), Date VARCHAR(20),tag VARCHAR(10))", con);
cmd2.ExecuteNonQuery();
con.Close();
con.Open();
SqlCommand cmd3 = new SqlCommand("insert into " + mytags.Text + " values ('" + Session + "','" + TextBox3.Text + "','" + TextBox4.Text + "','" + TextBox5.Text + "','" + mytags.Text + "')", con);
cmd3.ExecuteNonQuery();
label.Visible = true;
label.Text = "tabel created";
con.Close();
}
I have tried to remove the error and I got that the connection is not going to else condition. Please review the code and suggest if there is any mistake or any other solution for this.
Just change the SqlCommand.CommandText instead of creating a new SqlCommand every time. There is no need to close and reopen the connection.
// Create the first command and execute
var command = new SqlCommand("<SQL Command>", myConnection);
var reader = command.ExecuteReader();
// Change the SQL Command and execute
command.CommandText = "<New SQL Command>";
command.ExecuteNonQuery();
The following should work. Keep single connection open all time, and just create new commands and execute them.
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command1 = new SqlCommand(commandText1, connection))
{
}
using (SqlCommand command2 = new SqlCommand(commandText2, connection))
{
}
// etc
}
Just enable this property in your connection string:
sqb.MultipleActiveResultSets = true;
This property allows one open connection for multiple datareaders.
I have not tested , but what the main idea is: put semicolon on each query.
SqlConnection connection = new SqlConnection();
SqlCommand command = new SqlCommand();
connection.ConnectionString = connectionString; // put your connection string
command.CommandText = #"
update table
set somecol = somevalue;
insert into someTable values(1,'test');";
command.CommandType = CommandType.Text;
command.Connection = connection;
try
{
connection.Open();
}
finally
{
command.Dispose();
connection.Dispose();
}
Update:
you can follow
Is it possible to have multiple SQL instructions in a ADO.NET Command.CommandText property? too
This is likely to be attacked via SQL injection by the way. It'd be worth while reading up on that and adjusting your queries accordingly.
Maybe look at even creating a stored proc for this and using something like sp_executesql which can provide some protection against this when dynamic sql is a requirement (ie. unknown table names etc). For more info, check out this link.
No one has mentioned this, but you can also separate your commands using a ; semicolon in the same CommandText:
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand comm = new SqlCommand())
{
comm.Connection = conn;
comm.CommandText = #"update table ... where myparam=#myparam1 ; " +
"update table ... where myparam=#myparam2 ";
comm.Parameters.AddWithValue("#myparam1", myparam1);
comm.Parameters.AddWithValue("#myparam2", myparam2);
conn.Open();
comm.ExecuteNonQuery();
}
}
Multiple Non-query example if anyone is interested.
using (OdbcConnection DbConnection = new OdbcConnection("ConnectionString"))
{
DbConnection.Open();
using (OdbcCommand DbCommand = DbConnection.CreateCommand())
{
DbCommand.CommandText = "INSERT...";
DbCommand.Parameters.Add("#Name", OdbcType.Text, 20).Value = "name";
DbCommand.ExecuteNonQuery();
DbCommand.Parameters.Clear();
DbCommand.Parameters.Add("#Name", OdbcType.Text, 20).Value = "name2";
DbCommand.ExecuteNonQuery();
}
}
Here you can find Postgre example, this code run multiple sql commands (update 2 columns) within single SQL connection
public static class SQLTest
{
public static void NpgsqlCommand()
{
using (NpgsqlConnection connection = new NpgsqlConnection("Server = ; Port = ; User Id = ; " + "Password = ; Database = ;"))
{
NpgsqlCommand command1 = new NpgsqlCommand("update xy set xw = 'a' WHERE aa='bb'", connection);
NpgsqlCommand command2 = new NpgsqlCommand("update xy set xw = 'b' where bb = 'cc'", connection);
command1.Connection.Open();
command1.ExecuteNonQuery();
command2.ExecuteNonQuery();
command2.Connection.Close();
}
}
}
using (var connection = new SqlConnection("Enter Your Connection String"))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "Enter the First Command Here";
command.ExecuteNonQuery();
command.CommandText = "Enter Second Comand Here";
command.ExecuteNonQuery();
//Similarly You can Add Multiple
}
}
It worked for me.

Need help with database connection and query code

In my code below, the cmdquery works but the hrquery does not. How do I get another query to populate a grid view? Do I need to establish a new connection or use the same connection? Can you guys help me? I'm new to C# and asp. Here's some spaghetti code I put together. It may all be wrong so if you have a better way of doing this feel free to share.
if (Badge != String.Empty)
{
string cmdquery = "SELECT * from Employees WHERE Badge ='" + Badge + "'";
string hrquery = "SELECT CLOCK_IN_TIME, CLOCK_OUT_TIME FROM CLOCK_HISTORY WHERE Badge ='" + Badge + "'";
OracleCommand cmd = new OracleCommand(cmdquery);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
conn.Open();
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
this.xUserNameLabel.Text += reader["EMPLOYEE_NAME"];
this.xDepartmentLabel.Text += reader["REPORT_DEPARTMENT"];
}
OracleCommand Hr = new OracleCommand(hrquery);
Hr.Connection = conn;
Hr.CommandType = CommandType.Text;
OracleDataReader read = Hr.ExecuteReader();
while (read.Read())
{
xHoursGridView.DataSource = hrquery;
xHoursGridView.DataBind();
}
}
conn.Close();
Your data access code should generally look like this:
string sql = "SELECT * FROM Employee e INNER JOIN Clock_History c ON c.Badge = e.Badge WHERE e.Badge = #BadgeID";
using (var cn = new OracleConnection("your connection string here"))
using (var cmd = new OracleCommand(sql, cn))
{
cmd.Parameters.Add("#BadgeID", OracleDbType.Int).Value = Badge;
cn.Open();
xHoursGridView.DataSource = cmd.ExecuteReader();
xHoursGridView.DataBind();
}
Note that this is just the general template. You'll want to tweak it some for your exact needs. The important things to take from this are the using blocks to properly create and dispose your connection object and the parameter to protect against sql injection.
As for the connection question, there are exceptions but you can typically only use a connection for one active result set at a time. So you could reuse your same conn object from your original code, but only after you've completely finished with it from the previous command. It is also okay to open up two connections if you need them. The best option, though, is to combine related queries into single sql statement when possible.
I'm not even going to get into how you should be using usings and methods :p
if (Badge != String.Empty)
{
string cmdquery = "SELECT * from Employees WHERE Badge ='" + Badge + "'";
string hrquery = "SELECT CLOCK_IN_TIME, CLOCK_OUT_TIME FROM CLOCK_HISTORY WHERE Badge ='" + Badge + "'";
OracleCommand cmd = new OracleCommand(cmdquery);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
conn.Open();
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
this.xUserNameLabel.Text += reader["EMPLOYEE_NAME"];
this.xDepartmentLabel.Text += reader["REPORT_DEPARTMENT"];
}
OracleCommand Hr = new OracleCommand(hrquery);
Hr.Connection = conn;
Hr.CommandType = CommandType.Text;
OracleDataReader read = Hr.ExecuteReader();
//What's this next line? Setting the datasource automatically
// moves through the data.
//while (read.Read())
//{
//I changed this to "read", which is the
//datareader you just created.
xHoursGridView.DataSource = read;
xHoursGridView.DataBind();
//}
}
conn.Close();

Categories