Im making a project in C# ASP.NET with MySQL. Im trying to open a MySql connection correctly. Also close/dispose this connection correctly. Becouse it gives That error sometimes
"mySQL ERROR: system lacked sufficient buffer space or because a queue
was full."
Anyway so I decided to use "using" method my current connection method like that;
MySqlConnection baglanti = new MySqlConnection(ConfigurationManager.ConnectionStrings["mysqlbaglanti"].ToString());
void GirisYap()
{
using (var cn = baglanti)
{
cn.Open();
using (MySqlCommand cmd = new MySqlCommand("SELECT * FROM kullanicilar WHERE kullaniciadi='" + txtKullaniciAdi.Text + "' AND sifre='" + txtSifre.Text + "'"))
{
using (MySqlDataReader oku = cmd.ExecuteReader())
{
if (oku.Read())
{
Session.Add("AdSoyad", oku["AdSoyad"]);
Session.Add("sesid", oku["kullaniciid"]);
Response.Redirect("AnaSayfa.aspx");
}
else
{
lblDurum.Text = "Yanlış Kullanıcı Adı/Şifre !";
}
}
}
}
}
but its gives an error that "Connection must be valid and open." what am I doing wrong?
in using you should create new IDisposible object. When you exit using scope, it will be disposed.
In your code, you generate connection during class object construction. After first usage of cn, your baglanti object will be disposed. After first usage, you cannot open connection. Hence, you should generate connection object in using statement.
All above is advice, not solution of your problem. Your problem is that, command object does not have connection object. You can pass connectin object to command object via constructor
You should use like:
string connectionStr = ConfigurationManager.ConnectionStrings["mysqlbaglanti"].ToString());
void GirisYap()
{
using (var cn = new new MySqlConnection(connectionStr))
{
cn.Open();
// command object should take connection object
using (MySqlCommand cmd = new MySqlCommand("SELECT * FROM kullanicilar WHERE kullaniciadi='" + txtKullaniciAdi.Text + "' AND sifre='" + txtSifre.Text + "'", cn))
{
........
}
}
Related
private void comT_SelectedIndexChanged(object sender, EventArgs e)
{
if (comT.SelectedIndex != -1)
{
SqlCommand cmd = new SqlCommand(#"SELECT ISNULL(substring(MAX(tCode),3,2),'00')
FROM Teacher
WHERE dCode = '" + comT.SelectedValue.ToString() + "'", MUControlClass.con);
SqlDataReader dr = cmd.ExecuteReader();
dr.Read(); <--HERE IS ERROR **"ExecuteReader requires an open and available Connection. The connection's current state is closed."**
if (dr[0].ToString() != "00")
{
int dugaar = Convert.ToInt32(dr[0]) + 1;
if (dugaar > 9)
{
msk.Text = comT.SelectedValue.ToString() + dugaar.ToString();
}
else
msk.Text = comT.SelectedValue.ToString() + "0" + dugaar.ToString();
}
else
{
msk.Text = comT.SelectedValue.ToString() + "01";
}
dr.Close();
}
}
ExecuteReader requires an open and available Connection. The connection's current state is closed. Error
The immediate error is that the connection is not open, as it told you; so ... open it; however, there are a lot of other serious problems here - most notably "SQL injection", but also non-disposed objects. You can fix SQL injection by using parameters, and the non-disposed problem with lots of using, but: I strongly suggest you make use of tools that will help you get this right by default. For example:
private void comT_SelectedIndexChanged(object sender, EventArgs e)
{
if (comT.SelectedIndex != -1)
{
using (var conn = new SqlConnection(yourConnectionString))
{
string max = conn.QuerySingle<string>(#"
SELECT ISNULL(substring(MAX(tCode),3,2),'00')
FROM Teacher
WHERE dCode = #dCode", new { dCode = comT.SelectedValue.ToString() });
if (max != null)
{
// your parse/etc logic
}
}
}
}
This is:
moving our connection lifetime to be local to this method, which will stop a lot of connection usage problems
using "Dapper" to provide the QuerySingle<T> code
which means you don't need to mess with commands or readers
adding parameter usage via #dCode and the new { dCode = ... } usage
Note it might look like we've still not opened the connection here, but Dapper is happy to do that for us; if it is given a closed connection, it opens the connection for the duration of the query only.
Wherever the connection is created in MUControlClass you need to call con.Open().
Your connection is not opened.
Simplified flow of connection and interaction with database is like this:
using(SqlConnection con = new SqlConnection(yourConnectionString))
{
con.Open() // You do not open this one so it returns that error
using(SqlCommand cmd = new SqlCommand(yourSqlCommand, con))
{
using(SqlDataReader dr = cmd.ExecuteReader())
{
if(dr.Read())
{
// Do something
}
}
}
}
We do not need to do close/destroy anything as long as it is wrapped in using since they all implements IDisposable
Through the information I have found searching here on stackoverflow, I have what I think is 90% of this solved but because of how OleDbConnection is converted to define SqlConnection, the call to the class with the connection and test script wants definition I am unsure how to provide.
I've used these pages to get what I have so far
How to create an SqlConnection in C# to point to UDL file
Calling an SQL Connection method in C#
private static string CONNECTION_NAME = #"C:\Temp\DisplayDB.udl";
public static class MyConnection
{
public static SqlConnection GetSqlConnection()
{
var udlInfo = new OleDbConnection($"File Name={CONNECTION_NAME}");
return CreateSqlConnection(udlInfo);
}
public static SqlConnection CreateSqlConnection(OleDbConnection udlInfo)
{
try
{
string CONNECTION_STRING = $"Database={udlInfo.Database};Server={udlInfo.DataSource};User ID=User;Password=13245;Integrated Security=True;connect timeout = 30";
var connection = new SqlConnection(CONNECTION_STRING);
connection.Open();
return connection;
}
catch
{
Console.WriteLine($"{CONNECTION_NAME} Not found");
return null;
}
}
}
private void DBCheck()
{
// The line below is my issue, mouseover error of ".CreateSqlConnection"
// says there is no argument given that corresponds to the required
// formal parameter 'udlInfo' of
// 'MainWindow.MyConnection.CreateSqlConnection(OleDbConnection)'
using (var con = MyConnection.CreateSqlConnection())
{
con.Open();
var command = new SqlCommand("IF DB_ID ('CodeTest') IS NULL " +
"BEGIN " +
"USE MASTER " +
"CREATE DATABASE CodeTest" +
" END", con);
var reader = command.ExecuteReader();
reader.Close();
con.Close();
}
}
I expect the WPF to use the Database and Server from the UDL file to make the SqlConnection so I can run queries and commands. I understand the security part of UDL in plain text but I do not want hard coded values as this application will be used in various environments nor do I want those values to need definition on each launch of the app.
The error with ExecuteReader: Connection property has not been initialized is giving me a fit. I think I have it set up right. I will show you how I create the mssql connection and then what I am requesting, and the class I created to read/write and open/close the connection. (Three different parts of the app but I just lumped them together so you could see the actual logic flow I hope.)
What am I missing, or where am I supposed to put the connection? Example? I appreciate the help!
Here is the using statement I start with:
using (MSSQL mssqldb = new MSSQL(Constants.msSqlServer, Constants.msSqlDb, Constants.msSqlUid, Constants.msSqlPswd))
Here is where I say "Hey, get me my data using my MSSQL class"
using (var results = mssqldb.Read("SELECT TOP 1 * FROM AlertLog ORDER BY AlarmID DESC"))
{
results.Read();
legacyAlert = Int32.Parse(results["AlarmId"].ToString().Trim());
}
Here is the MSSQL class
class MSSQL : IDisposable
{
public MSSQL(string server, string database, string uid, string pswd)
{
string msSqlConnectionString = #"Data Source=" + server + ";Initial Catalog=" + database + ";user id=" + uid + ";password=" + pswd;
SqlConnection msqlConnection = new SqlConnection(msSqlConnectionString);
msqlConnection.Open();
Console.WriteLine("MS SQL OPEN!");
}
public void Write(string sql)
{
using (SqlCommand myCommand = new SqlCommand(sql, msqlConnection))
myCommand.ExecuteNonQuery();
}
public SqlDataReader Read(string sql)
{
using (SqlCommand myCommand = new SqlCommand(sql, msqlConnection))
return myCommand.ExecuteReader();
}
public void Dispose()
{
try {
msqlConnection.Close();
}
catch (SqlException ex) {
Console.Error.WriteLine("MS SQL Error - Closing Database");
Console.Error.WriteLine(ex);
}
msqlConnection.Dispose();
}
private SqlConnection msqlConnection;
}
msqlConnection is null.
Your constructor creates a local variable named msqlConnection, but does not assign to the field.
I have been doing applications on Java, connected with MySQL, but now I am doing C# with Oracle.
Here is the code I've got so far:
using System.Data.OracleClient;
namespace Chat
{
class DBconnector
{
static private string GetConnectionString()
{
return "Data Source=myserver.server.com;Persist Security Info=True;" +
"User ID=myUserID;Password=myPassword;Unicode=True";
}
static public void ConnectAndQuery()
{
string connectionString = GetConnectionString();
using(OracleConnection conn = new OracleConnection())
{
conn.ConnectionString = connectionString;
conn.Open();
Console.WriteLine("State: " + conn.State);
Console.WriteLine("Connction String: " + conn.ConnectionString);
OracleCommand command = conn.CreateCommand();
string sql = "SELECT * FROM users";
command.CommandText = sql;
OracleDataReader reader = command.ExecuteReader();
while(reader.Read())
{
string myField = (string)reader["MYFIELD"];
Console.WriteLine(myField);
}
}
}
}
}
What is hacking me is that I don't know what to type in exchange of "myserver.server.com", "myUserID" and the "myPassword" in the connectionString.
I suppose it's "localhost/" and smth like that, but with Oracle I don't really have the same visual interface as with MySQL in the browser and thus I am kinda' lost.
I followed this tutorial: Instant Oracle using C#
and I am doing the case with including the connection String directly in my code, but not using the tsanames.ora external file.
Long story short -> I am not sure how to modify the connection string for my own database and if there are any other mistakes or suggestions - feel free to state them.
I'm not sure if you can do this without modifying your tnsnames, but it's not hard:
YOURSERVER = (DESCRIPTION = (ADDRESS = (PROTOCOL= TCP)
(Host= <your_server_hostname_or_IP>)(Port= <port>))(CONNECT_DATA = (SID = <DB_instance name>)) )
If you have doubts on how to fill these up, you should check with your nearest DBA.
Then just add YOURSERVER in:
return "Data Source=YOURSERVER; ...
Username and password are those related to the schema you want to connect.
I am using Visual Studio 2010 (C#) with mysqlConnector and everything seems to be fine.
However, when I try to request something from the server I get this error:
"There is already an open DataReader associated with this Connection which must be closed first."
This is my code:
gc.connect();
List<Conseiller> conseillers = gc.getAllConseillers();
--
public void connect()
{
string connStr = "SERVER=localhost;UID=root;DATABASE=Projet;Password=root";
oConn = new MySqlConnection(connStr);
try
{
oConn.Open();
Console.WriteLine("Successfully connected to the data base");
}
catch (OdbcException caugth)
{
/* Traitement de l'erreur */
Console.WriteLine(caugth.Message);
}
}
--
public List<Conseiller> getAllConseillers()
{
MySqlCommand oComm = oConn.CreateCommand();
oComm = oConn.CreateCommand();
Console.WriteLine("SELECT * FROM conseillers");
oComm.CommandText = "SELECT * FROM conseillers";
MySqlDataReader oReader = oComm.ExecuteReader(); // Error here
}
Where I am wrong ?
don't try to separate the connect with the get data. The call to Open may in-fact not go to the database at all and you will not detect issues at that point. Note the using statement to close the connection. add SEH as required
List<Conseiller> conseillers = gc.getAllConseillers();
public void getAll() {
string connStr = "SERVER=localhost;UID=root;DATABASE=Projet;Password=root";
using (oConn = new MySqlConnection(connStr))
using (MySqlCommand oComm = oConn.CreateCommand())
{
oConn.Open();
oComm.CommandText = "SELECT * FROM conseillers";
MySqlDataReader oReader = oComm.ExecuteReader(); // no Error here
// user reader here
} catch (OdbcException caugth) {
/* Traitement de l'erreur */
Console.WriteLine(caugth.Message);
}
}
You're not disposing of your objects, which basically means that your previous call to getAllConseillers, or a similar method, opened a data reader that is still open.
The following objects in your question are disposable (ie. implements IDisposable), you should dispose of them all:
MySqlConnection
MySqlCommand
MySqlDataReader
Basically, I would change the code as shown to this:
using (var gc = new Whatever())
{
gc.connect();
List<Conseiller> conseillers = gc.getAllConseillers();
}
--
public void connect()
{
string connStr = "SERVER=localhost;UID=root;DATABASE=Projet;Password=root";
oConn = new MySqlConnection(connStr);
try
{
oConn.Open();
Console.WriteLine("Successfully connected to the data base");
}
catch (OdbcException ex)
{
/* Traitement de l'erreur */
Console.WriteLine(ex.Message);
oConn.Dispose();
oConn = null;
// optional: throw;
}
}
--
public List<Conseiller> getAllConseillers()
{
using (MySqlCommand oComm = oConn.CreateCommand())
{
Console.WriteLine("SELECT * FROM conseillers");
oComm.CommandText = "SELECT * FROM conseillers";
using (MySqlDataReader oReader = oComm.ExecuteReader()) // No error here
{
// process the result in oReader here
return ...;
}
...
}
...
}
A few suggestions that may help:
First, in your code above you have called CreateCommand twice and don't need to.
Secon, you can instantiate your Command a little different to make this easier to read:
MySqlCommand oComm = new MySqlCommand("Select * from conseillers", oConn);
then call the ExecuteReader.
Third, your code above doesn't show when the connection is open. Are you sure it's open? Are you sure you haven't already called a data reader with the open connection and didn't close it?
Fourth, you should always open the connection as late as possible and close it as early as possible. The code you have seems like you are going to open the connection and leave it open but I'm not really sure of your intent.
I would suggest using the Using syntax:
Using connection As New SqlConnection(connectionString)
Dim command As New SqlCommand(queryString, connection)
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
Try
While reader.Read()
Console.WriteLine(String.Format("{0}, {1}", _
reader(0), reader(1)))
End While
Finally
' Always call Close when done reading.
reader.Close()
End Try
End Using
Modify the above code for your situation....