I am facing an issue with ExecuteReader(). When I am writing MySqlDataReader reader = cmd.ExecuteReader();, I have a red line under cmd.ExecuteReader(). I am using Windows Form Application to read database from Microsoft SQL Server and using C# and OOP.
SqlConnection con = new SqlConnection(constring);
con.Open();
if (con.State == System.Data.ConnectionState.Open)
{
string q = "SELECT * from BuildingA30 where CONVERT(VARCHAR, FlatNo) = N'" + a11 + "' ";
Console.WriteLine("Read all");
Console.WriteLine(q);
SqlCommand cmd = new SqlCommand(q, con);
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
textBox1.Text = reader.GetString("tenantname");
textBox2.Text = reader.GetString("FlatNo");
}
textBox1.Text = q.ToString();
MessageBox.Show("Connection success");
}
Problem is that SqlCommand.ExecuteReader returns a SqlDataReader, not a MySqlDataReader.
Here:
SqlCommand cmd = new SqlCommand(q, con);
MySqlDataReader reader = cmd.ExecuteReader();
You're mixing ADO.NET providers. Either use the SQL Server provider classes (if the database is SQL Server), or the MySql ones if it's MySql. Not both.
You install Dapper, then you don't have to waste your life writing boring, menial data reader code..
With Dapper that entire code you've written (yep all of it) would become something like `
using(var con = new MySqlConnection(...)){
var rental = con.Query<RentalInfo>(
"SELECT * FROM BuildingA30 WHERE flatNo = #f",
new { f = all }
};
//use your rental object
This code is massively improved over the one you have there because:
it's simple, quick to write, easy to read and debug
it uses parameters and doesn't suffer from sql injection hacking risks - yours does
it is strongly typed and can be async (note, mysql hasn't implemented async for their db provider, apparently but using async is a good habit to get into) - you just need to create a class called RentalInfo and add the relevant names properties to it;
it doesn't call functions on the left hand side of an operator in the WHERE clause. Always a bad idea; don't call functions on millions of rows, call functions on constants and leave table data alone
http://dapper-tutorial.net
Note: I have no affiliation to Dapper or the guys who maintain that tutorial site
Related
I'm trying to get the value of a Field (User Access level it's 1 or 2 in string format) after login
OleDbConnection connection = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=dsms.accdb");
connection.Open();
OleDbDataReader reader = null;
OleDbCommand command = new OleDbCommand("SELECT AL From Users WHERE Username='" + textusername.text + "'", connection);
reader = command.ExecuteReader();
if( reader.HasRows)
{
MessageBox.Show("success","status");
label1.Text = reader.GetString(1);
}
else
MessageBox.Show("failur", "status");
connection.Close();
I did execute the code in Access and it's was totally fine
but in the program, it says "No data exist for the row/column"
The main problem in your code is the fact that you need to call reader.Read() to get anything out from a DataReader. Just calling HasRows doesn't position the reader on the first record of your query.
There are other problems in your code.
Disposable objects like connections, commands and readers should be created in a using statement to ensure proper disposition after use and because you have only one field in your query, you should use the index 0 to retrieve it not 1.
Finally the most important one. You should NEVER concatenate strings to build an sql query. In this way a malicious user could write anything in your textbox, even valid sql commands that could be executed against your database. It is called Sql Injection and if you search for these terms you will find very detailed discussions about it. However, to avoid this problem (and others like parsing input with apostrophes) you use a parameterized query like below.
using(OleDbConnection connection = new OleDbConnection(.....))
using(OleDbCommand command = new OleDbCommand("SELECT AL From Users WHERE Username=#name", connection);
{
connection.Open();
command.Parameters.Add("#name", OleDbType.VarWChar).Value = txtusername.text;
using(OleDbDataReader reader = command.ExecuteReader())
{
if( reader.Read())
{
MessageBox.Show("success","status");
label1.Text = reader.GetString(0);
}
else
MessageBox.Show("failur", "status");
}
}
C# visual studio 2012 professional asp.net
I have a table containing usernames: Josh, Jeremy, Jared, Justin...
And I created a web page gridview that shows the entire table but I only want it to show Justin and nothing else.
How do I do this?
Here's some code that didn't work:
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True");
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
SqlDataReader rs;
con.Open();
SqlParameter uName = new SqlParameter("paramFName", Account.Text);
cmd.Parameters.Add(uName);
cmd.CommandText = "SELECT * FROM Transactions WHERE FName=#paramFName";
rs = cmd.ExecuteReader();
cmd.Parameters.Clear();
rs.Close();
Am I supposed to create a view of the table? I tried but wasn't successful.
tips?
You simply missed the "#" at the parameter name:
SqlParameter uName = new SqlParameter("#paramFName", Account.Text);
In case of your where-clause this has the effect that you didn't provide anything for the specified parameter which simply let the query provider ignore this condition, which results in the effective query SELECT * FROM Transactions.
Beside you should think about using the using block:
using (SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True"))
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = "SELECT * FROM Transactions WHERE FName=#paramFName";
cmd.Parameters.AddWithValue("#paramFName", Account.Text);
con.Open();
using (var rs = cmd.ExecuteReader())
{
//ToDo: Do something with the reader.
}
}
And another hint: If you need to fill up a DataTable with the result, you can use a SqlDataAdapter instead of using the data reader:
using (var adapter = new SqlDataAdapter(cmd))
{
var dataTable = new DataTable();
dataTable.TableName = "QueryResult";
adapter.Fill(dataTable);
return dataTable;
}
If you are trying to select the first 10 names for example then you need to change your SQL Select to the following:
cmd.CommandText = "SELECT TOP 10 * FROM Transactions WHERE FName=#paramFName";
Is that what you were after?
EDIT
OK so you are not actually displaying your data anywhere which is the actual problem.
You need to create a datatable and display it in a gridview.
Check out the following links for examples:
Gridview examples
MSDN Gridview examples
Your code seems fine, although you do not provide much information.
If you're using SQL Server 2012 have a look at the keywords OFFSET and FETCH.
For earlier versions you need to use ROW_NUMBER OVER PARTITION
As a good practice you should always limit the number of elements returned.
Ok either I'm really tired or really thick at the moment, but I can't seem to find the answer for this
I'm using ASP.NET and I want to find the amount of rows in my table.
I know this is the SQL code: select count(*) from topics, but how the HECK do I get that to display as a number?
All I want to do is run that code and if it = 0 display one thing but if it's more than 0 display something else. Help please?
This is what I have so far
string selectTopics = "select count(*) from topics";
// Define the ADO.NET Objects
SqlConnection con = new SqlConnection(connectionString);
SqlCommand topiccmd = new SqlCommand(selectTopics, con);
if (topiccmd == 0)
{
noTopics.Visible = true;
topics.Visible = false;
}
but I know I'm missing something seriously wrong. I've been searching for ages but can't find anything.
PHP is so much easier. :)
Note that you must open the connection and execute the command before you can access the result of the SQL query. ExecuteScalar returns a single result value (different methods must be used if your query will return an multiple columns and / or multiple rows).
Notice the use of the using construct, which will safely close and dispose of the connection.
string selectTopics = "select count(*) from topics";
// Define the ADO.NET Objects
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand topiccmd = new SqlCommand(selectTopics, con);
con.Open();
int numrows = (int)topiccmd.ExecuteScalar();
if (numrows == 0)
{
noTopics.Visible = true;
topics.Visible = false;
}
}
ExecuteScalar is what you're looking for. (method of SqlCommand)
Btw, stick with C#, there's no way PHP is easier. It's just familiar.
You need to open the connection
This might work :
SqlConnection sqlConnection1 = new SqlConnection("Your Connection String");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "select count(*) from topics";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
// Data is accessible through the DataReader object here.
sqlConnection1.Close();
Similar Question: C# 'select count' sql command incorrectly returns zero rows from sql server
Why my query does not return results?
I'm using C#.
It returns column headers but no rows. Is there a problem with my select statement?
here's my code :
conn = new SQLiteConnection("Data Source=local.db;Version=3;New=False;Compress=True;");
DataTable data = new DataTable();
SQLiteDataReader reader;
using (SQLiteTransaction trans = conn.BeginTransaction())
{
using (SQLiteCommand mycommand = new SQLiteCommand(conn))
{
mycommand.CommandText = "SELECT * FROM TAGTABLE WHERE TAG = '"+tag+"' ;";
reader = mycommand.ExecuteReader();
}
trans.Commit();
data.Load(reader);
reader.Close();
reader.Dispose();
trans.Dispose();
}
return data;
The TAGTABLE has following fields:
TID int,
Tag varchar(500),
FilePath varchar(1000)
You don't need the transaction, try the following:
DataTable data = new DataTable();
using (SQLiteConnection conn = new SQLiteConnection("Data Source=local.db;Version=3;New=False;Compress=True;"))
using (SQLiteCommand mycommand = new SQLiteCommand(conn))
{
mycommand.CommandText = "SELECT * FROM TAGTABLE WHERE TAG = #tag;";
mycommand.Parameters.AddWithValue("#tag", tag);
conn.Open();
using (SQLiteDataReader reader = mycommand.ExecuteReader())
{
data.Load(reader);
}
}
return data;
The most likely reason this won't return anything is if the SELECT doesn't yield any results.
Also note that anything implementing the IDisposable interface can be used in conjunction with the using statement, so manual closing / disposal of objects afterwards is not required.
Notice that the SQL has changed to use a parameterized query, this will help reduce the likelihood of SQL injection attacks, and is generally cleaner.
Since you don't show sample data and what should be returend some general pointers only:
The way you build the SQL is wide open to SQL incjection (a serious security issue)
Depending on the value of tag (for example if it contains ') the above SQL Statement would do something you don't expect
Since everything is wrappend in using (a good thing!) the question is, whether there is some exception thrown inside the using block (check with the debugger)
why are you using a transaction ? I can't see any reason which makes that necessary...
Please show some sample data with param value and expected result...
I am using C# to write a method that returns the following information about a table:
column names, column types, column sizes, foreign keys.
Can someone point me in the right direction on how to accomplish this ?
This really depends on how you communicate with your database. If you are using LinqToSQL or another similar ORM this would be pretty easy but if you want to get these values via a query I'd suggest you use the INFORMATION_SCHEMA views as these are fast and easy to query.
e.g.
select * from information_schema.columns where table_name = 'mytable'
To get the FK and Schema you should be able to use:
DA.FillSchema()
DS.Table("Name").PrimaryKey
OR calling sp_fkey using the method demonstrated below
Code Snippet from AND Another Link
private void LoanSchema()
{
private List<String> tablesList = new List<String>();
private Dictionary<String, String> columnsDictionary = new Dictionary<String, String>();
string connectionString = "Integrated Security=SSPI;" +
"Persist Security Info = False;Initial Catalog=Northwind;" +
"Data Source = localhost";
SqlConnection connection = new SqlConnection();
connection.ConnectionString = connectionString;
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "exec sp_tables";
command.CommandType = CommandType.Text;
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
tablesList.Add(reader["TABLE_NAME"].ToString());
}
reader.Close();
command.CommandText = "exec sp_columns #table_name = '" +
tablesList[0] + "'";
command.CommandType = CommandType.Text;
reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
columnsDictionary.Add(reader["COLUMN_NAME"].ToString(), reader["TYPE_NAME"].ToString());
}
}
You can use the SqlDataAdapter.FillSchema() method.
Alternatively you can use the SqlDataAdapter.Fill() method after setting the MissingSchemaAction property of the SqlDataAdapter to AddWithKey. But if you only want the schema you must ensure that your query returns no rows. This can be accomplished by adding a statement like WHERE 1=2 to your query.
If you are using MS SQL Server then You should definately have a look at SMO namespace (server management objects).
There are objects which You can use in .net responsible for all kinds of things in a database (including but not limited to tables, columns, constraints etc.)
I think you need the System.Data.DataTable class:
http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx