Reading values from SQL database in C# - c#

i have just started learning C# and i can write data to the database without a problem. But i'm having problems with reading, the SQL executes fine but i'm having issues with storing it. How would i store the four columns that should be returned and then show them as a message box? Thanks.
SqlCommand myCommand = new SqlCommand("select * from Requests where Complete = 0", myConnection);
SqlDataReader myReader = myCommand.ExecuteReader();
while (myReader.Read())
Console.WriteLine(myReader["Username"].ToString());
Console.WriteLine(myReader["Item"].ToString());
Console.WriteLine(myReader["Amount"].ToString());
Console.WriteLine(myReader["Complete"].ToString());

One problem is missing braces after the while
while (myReader.Read())
{ // <<- here
Console.WriteLine(myReader["Username"].ToString());
Console.WriteLine(myReader["Item"].ToString());
Console.WriteLine(myReader["Amount"].ToString());
Console.WriteLine(myReader["Complete"].ToString());
} // <<- here
if you skip the braces only the first line will be processed in each loop, the rest will be processed after the loop, then myReader is past the last row.

Don't forget to use the using(){} block :
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand("select * from Requests where Complete = 0", connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine(reader["Username"].ToString());
Console.WriteLine(reader["Item"].ToString());
Console.WriteLine(reader["Amount"].ToString());
Console.WriteLine(reader["Complete"].ToString());
}
}
}

Personally I'd write a class with 4 properties (with matching names and types), then use "dapper" (http://code.google.com/p/dapper-dot-net/):
var data = connection.Query<Request>(
"select * from Requests where Complete = 0").ToList();
With something like:
public class Request {
public string Username{get;set;}
...
public bool Complete {get;set;}
}
Dapper is free, simple, has parameterisation to avoid SQL-injection, and is very very fast.

I would create an object with properties that holds those values and then pass that object around as needed.
public class YourObjectName
{
public string Username { get; set; }
public string Item { get; set; }
public string Amount { get; set; }
public string Complete { get; set; }
}
YourObjectName a = new YourObjectName();
a.Username = Reader['Username'].ToString();

i know its a bit late but you can use local string variables,or string array or list insert the data in the database there and then call it in your console write line

Related

Invalid Column Name | C#

I am trying to figure out how to collect data from a database with c#.
I am stuck on a SQL command, and I can't really figure out how to fix it.
My error is: Invalid Column Name
This is my database:
MyDatabase
And this is my connection class:
namespace CarDAL
{
public class ConnectionClass
{
private string Connectionstring =
"MYCONNECTIONSTRING";
public List<string> SoortSelectList(string KarakterSoort)
{
KarakterSoort = "Defensive";
List<string> soortList = new List<string>();
using (SqlConnection connection = new SqlConnection(Connectionstring))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand("SELECT * FROM dbo.Karakter WHERE KarakterSoort = Defensive", connection))
{
using (IDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
soortList.Add(dr.GetValue(0).ToString());
soortList.Add(dr.GetValue(1).ToString());
}
}
}
}
return soortList;
}
I think after WHERE that the problem is, but I don't know (and can't find) the right solution for my problem.
Your WHERE clause here:
WHERE KarakterSoort = Defensive
compares the value in the KarakterSoort column to the value in the Defensive column.
Is that really what you want???
Quite possibly, you want to compare to a string literal - then you need to put this into single quotes like this:
WHERE KarakterSoort = 'Defensive'
Now you're selecting all rows where the KarakterSoort column contains the value Defensive
Or if you might want compare to some other value in the future - use a parameter in your query string:
WHERE KarakterSoort = #DesiredValue
and declare it
cmd.Parameters.Add("#DesiredValue", SqlDbType.VarChar, 100);
and set its value before your run the command:
cmd.Parameters["#DesiredValue"].Value = "Defensive";

Get value from class

So i have a class Take for connecting to mysql. In that class I have a method to call a query to take the last record from mysql table.
public void Balance()
{
string query = "SELECT balance FROM history ORDER BY id DESC LIMIT 1 ";
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.ExecuteNonQuery();
}
}
In the main form I'm calling that class and that method
take.Balance();
I know, that from code above, i don't get any value but NULL, so i am asking how i can take value from that query and put it in the TextBox in the main form?
Personally, I think you should improve your basic knowledge of programming. There are two big problems in your example code:
You want to get the value, but your function is void, not return anything even set the value to some variable
ExecuteNonQuery is not your case.
For example:
public string Balance()
{
string query = "SELECT balance FROM history ORDER BY id DESC LIMIT 1 ";
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
return cmd.ExecuteScalar();
}
}
Let's have look:
// You probably want to return value: decimal, not void
public decimal Balance() {
// Make sql readable
string query =
#"SELECT balance
FROM history
ORDER BY id DESC
LIMIT 1 ";
// do not cache connection, but create a new one instead
using (MySqlConnection conn = new MySqlConnection(connectionStringHere)) {
conn.Open();
// wrap IDisposable into using
using (MySqlCommand cmd = new MySqlCommand(query, conn)) {
// you want to return values: ExecuteReader (or ExecuteScalar)
// instead of ExecuteNonQuery
using (var reader = cmd.ExecuteReader()) {
if (reader.Read())
return Convert.ToDecimal(reader.GetValue(0));
else
return 0m; // cursor is empty, let's return 0
}
}
}
}
There are two things to consider. First, the query
"SELECT balance FROM history ORDER BY id DESC LIMIT 1"
is a query in the sense that some useful data from the database should be returned, it should not be executed with a the method ExecuteNonQuery, which is intended to return the number of rows affected by a non-query statement. Second, the return type of Balance would have to be changed to some other type than void, say int or something similar, which would have to be returned to the caller.

C# getAll Function advice

Hi I am trying to create CRUD functions in C# but am stuck on my first one which is FetchALL, as so far it says not all code path returns a value.
Heres my code so far
public SqlDataReader FetchAll(string tableName)
{
using (SqlConnection conn = new SqlConnection(_ConnectionString,))
{
string query = "SELECT * FROM " + tableName;
SqlCommand command = new SqlCommand(query, conn);
using (SqlDataReader reader = command.ExecuteReader())
conn.Open();
conn.Close();
}
}
}
}
I can give you more information, thanks
You have a return type of SqlDataReader, but you aren't returning anything anywhere in your code. At the very least you should declare your data reader and return it like this:
public SqlDataReader FetchAll(string tableName)
{
SqlDataReader reader;
using (SqlConnection conn = new SqlConnection(_ConnectionString))
{
string query = "SELECT * FROM " + tableName;
// added using block for your command (thanks for pointing that out Alex K.)
using (SqlCommand command = new SqlCommand(query, conn))
{
conn.Open(); // <-- moved this ABOVE the execute line.
reader = command.ExecuteReader(); // <-- using the reader declared above.
//conn.Close(); <-- not needed. using block handles this for you.
}
}
return reader;
}
Note, I've noted a few other problems I saw as well, which you can see by my comments.
Also, I want to point out something very important: you should always avoid string concatenation in queries as this opens you up to the risk of a SQL injection attack (as gmiley has duly pointed out). In this case, you should create an enum which contains values associated with all the possible table names, and then use a dictionary to look up the table names based on their enum values. If a user provides an invalid/unknown value, you would then thrown an argument exception.
This isn't the end of your problems, though (as Default has pointed out). You can't create the connection in a using block, which disposes and closes as soon as it exits the block, and then use the SqlDataReader that is returned from the method. If I were you, I'd return a DataSet instead of a SqlDataReader. Here's how I'd do it:
First, create your enum of possible table values:
public enum Table
{
FirstTable,
SecondTable
}
And a dictionary that maps table enum values to the table names (which you will populate in your static constructor):
private static Dictionary<Table, string> _tableNames = new Dictionary<Table, string>(); // populate this in your static constructor.
And then here is your method to fetch the data:
public static System.Data.DataSet FetchAll(Table fromTable)
{
var ret = new System.Data.DataSet();
using (var conn = new System.Data.SqlClient.SqlConnection(_connectionString))
{
string tableName = "";
if (!_tableNames.TryGetValue(fromTable, out tableName)) throw new ArgumentException(string.Format(#"The table value ""{0}"" is not known.", fromTable.ToString()));
string query = string.Format("SELECT * FROM {0}", tableName);
using (var command = new System.Data.SqlClient.SqlCommand(query, conn))
{
using (var adapter = new System.Data.SqlClient.SqlDataAdapter(command))
{
adapter.Fill(ret);
}
}
}
return ret;
}
One final note, I'd advise you name your class-level variables with lower camel case per convention, e.g. _connectionString.
Firstly you aren't returning anything from the method. I'd add, are you sure you want to return a SqlDataReader? It is declared within a using block, so it will be closed by the time you return it anyway. I think you should re-evaluate what this function should return.
You need a return statment for the method to return a value.

How can I reference data of DataGridView into SQL database in C#?

I am new to database and C#. I am building an EPOS software and I just want to
reference the data which is in DataGridView into SQL database (if I am saying it correct).
Ok, here is what I am trying to do:
as shown in the photo, I have customer1 order details (3 rows) in DataGridView and this details is only for one customer1. Now when I finish with customer1, its order details is saved in database. Next, when I finish with customer2 order, its details is saved in database. Next, customer3 order details will be saved in database.... and so on.
Now for example at some point in the future I want to read back / Edit (or check)
customer2 order details from database and populate it into DataGridView.
I have been thinking how to do it but I failed and I am confused.
Can you please provide me with an idea or code in how to check what did Customer2 order. thank you.
Create a Customer Model which represent your table. Then create a method which will return a collection. I'm going to assume you've got your connection string setup and know how to read it in your code using c#. So the code could look like:
public class Customer
{
public int Quantity { get; set; }
public string Description { get; set; }
public double Price { get; set; }
}
public List<Customer> GetCustomerData()
{
var list = new List<Customer>();
string sqlQuery = "SELECT Qty, Des, Price From MyTable Where Customer = SomeCustomer"; //Change accordingly
string connectionString = "Your Connection String";
using (var connection = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(sqlQuery, connection))
{
connection.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var c = new Customer();
c.Quantity = Convert.ToInt32(reader["Qty"]);
c.Description = reader["Des"].ToString();
c.Price = Convert.ToDouble(reader["Price"]);
list.Add(c);
}
}
}
}
return list;
}
Finnaly to display the data on the DataGrid you'll do:
MyGrid.ItemsSource = GetCustomerData(); //Change MyGrid to whatever you've named your grid
Please note: I haven't tested the above code so it might require some small changes. However it should give you a good idea.

Store the results in memory (List) using c#

I want to store many record that I query from database in list , one record has 10 fields, in order to loop it later.
But I have no idea to do that. Anyone can answer me please.
Below is a good practice to store data and loop through among them.
Create Model/POCO class as:
public class DataClassName
{
public int Id { get; set; }
public string Name { get; set; }
//Create properties according to your fields
}
Fill and get data list:
public List<DataClassName> GetDataList()
{
List<DataClassName> dataList = new List<DataClassName>();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "select * from TargetTableName";
cmd.CommandType = CommandType.Text;
try
{
using (SqlConnection connection =
new SqlConnection("YourConnectionString"))
{
cmd.Connection = connection;
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
dataList.Add(
new DataClassName()
{
Id = Convert.ToInt32(reader["ID"]),
Name = Convert.ToString(reader["Name"])
//Set all property according to your fields
});
}
}
}
}
catch(Exception ex_)
{
//Handle exception
}
return dataList;
}
Save data that is returned from GetDataList() into your datalist and loop through among the data as required.
Here's how you'd go about storing it in a DataTable:
SqlConnection conn = new SqlConnection("yourConnectionStringHere");
SqlCommand GetData = new SqlCommand();
GetData.Connection = conn;
GetData.CommandText = "select * from yourTable"; // or whatever your query is, whether ad hoc or stored proc
// add parameters here if your query needs it
SqlDataAdapter sda = new SqlDataAdapter(GetData);
DataTable YourData = new DataTable();
try
{
sda.Fill(YourData);
}
catch
{
sda.Dispose();
conn.Dispose();
}
If you have 10 fields, you'd be hard-pressed to store your data in a List<T> object. Your best bet would be to create a class tailored to the data you are looking to retrieve (if you want to take it a step further than the DataTable implementation above) with corresponding properties/fields.
Perhaps you could give a bit more information...
If you use the entity framework or similar to query the database, it will probably return an enumerable object.. you just need to call .ToList() on this to save it as a list.
Do you mean that you want to store this across web requests? Then you could store it in the HttpRuntime.Cache collection, allowing for it to expire after some time.
Alternatively store it in a static property. Session is also an option but it doesn't sound like the best option for this

Categories

Resources