If I have a DbCommand defined to execute something like:
SELECT Column1 FROM Table1
What is the best way to generate a List<String> of the returned records?
No Linq etc. as I am using VS2005.
I think this is what you're looking for.
List<String> columnData = new List<String>();
using(SqlConnection connection = new SqlConnection("conn_string"))
{
connection.Open();
string query = "SELECT Column1 FROM Table1";
using(SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
columnData.Add(reader.GetString(0));
}
}
}
}
Not tested, but this should work fine.
Loop through the Items and Add to the Collection. You can use the Add method
List<string>items=new List<string>();
using (var con= new SqlConnection("yourConnectionStringHere")
{
string qry="SELECT Column1 FROM Table1";
var cmd= new SqlCommand(qry, con);
cmd.CommandType = CommandType.Text;
con.Open();
using (SqlDataReader objReader = cmd.ExecuteReader())
{
if (objReader.HasRows)
{
while (objReader.Read())
{
//I would also check for DB.Null here before reading the value.
string item= objReader.GetString(objReader.GetOrdinal("Column1"));
items.Add(item);
}
}
}
}
Or a nested List (okay, the OP was for a single column and this is for multiple columns..):
//Base list is a list of fields, ie a data record
//Enclosing list is then a list of those records, ie the Result set
List<List<String>> ResultSet = new List<List<String>>();
using (SqlConnection connection =
new SqlConnection(connectionString))
{
// Create the Command and Parameter objects.
SqlCommand command = new SqlCommand(qString, connection);
// Create and execute the DataReader..
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
var rec = new List<string>();
for (int i = 0; i <= reader.FieldCount-1; i++) //The mathematical formula for reading the next fields must be <=
{
rec.Add(reader.GetString(i));
}
ResultSet.Add(rec);
}
}
If you would like to query all columns
List<Users> list_users = new List<Users>();
MySqlConnection cn = new MySqlConnection("connection");
MySqlCommand cm = new MySqlCommand("select * from users",cn);
try
{
cn.Open();
MySqlDataReader dr = cm.ExecuteReader();
while (dr.Read())
{
list_users.Add(new Users(dr));
}
}
catch { /* error */ }
finally { cn.Close(); }
The User's constructor would do all the "dr.GetString(i)"
Where the data returned is a string; you could cast to a different data type:
(from DataRow row in dataTable.Rows select row["columnName"].ToString()).ToList();
This version has the same purpose of #Dave Martin but it's cleaner, getting all column, and easy to manipulate the data if you wan't to put it on Email, View, etc.
List<string> ResultSet = new List<string>();
using (SqlConnection connection = DBUtils.GetDBConnection())
{
connection.Open();
string query = "SELECT * FROM DATABASE";
using (SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
var rec = new List<string>();
for (int i = 0; i <= reader.FieldCount - 1; i++)
{
rec.Add(reader.GetString(i));
}
string combined = string.Join("|", rec);
ResultSet.Add(combined);
}
}
}
}
Related
I want to concatenate the query result in c#. Below is the resulting image
In my code, I have done
using (MySqlConnection cn = new MySqlConnection(conn.ConnectionString))
{
string query = "SELECT m.`read_param` FROM mdc_request m WHERE m.`row_id` = #row_id";
cn.Open();
MySqlCommand cmd = new MySqlCommand(query, cn);
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#row_id", iterations.row_id);
reader = cmd.ExecuteReader();
while (reader.Read())
{
// here I want to save the result in one single variable
}
}
Update 1
As per #Rahul answer, I have done the following
public async Task YtlbusMethod(List<Iterations> ytlbus)
{
MySqlConnection cn = null;
int limitRequest = 10;
for (int i = 10; i > 0; i--)
{
foreach (var item in ytlbus)
{
using (cn = new MySqlConnection(conn.ConnectionString))
{
string query = "SELECT m.`time` FROM `mdc_meter_config` m WHERE m.`row_id` = #row_id";
cn.Open();
MySqlCommand cmd = new MySqlCommand(query, cn);
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#row_id", item.row_id);
reader = cmd.ExecuteReader();
while (reader.Read())
{
string time = (string)reader["time"];
if(item.time == time)
{
int sleeptime = Convert.ToInt32(item.time);
sleeptime = sleeptime * 1000;
Thread.Sleep(sleeptime);
Task.Factory.StartNew(() => PortHitmethod(item));
}
}
}
cn.Close();
// select query kerni hy ..jis main wohi data ay jo tu yahan pass ker raha hy... where k ander just tuny row id pass kerni hy.
//if(item.time== query main jo time aya hy woh)
//{
//}
}
}
}
public async Task PortHitmethod(Iterations iterations)
{
MySqlConnection cn = null;
List<string> data = new List<string>();
using (cn = new MySqlConnection(conn.ConnectionString))
{
string query = "SELECT m.`read_param` FROM mdc_request m WHERE m.`row_id` = #row_id";
cn.Open();
MySqlCommand cmd = new MySqlCommand(query, cn);
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#row_id", iterations.row_id);
reader = cmd.ExecuteReader();
while (reader.Read())
{
data.Add(reader["read_param"].ToString());
}
}
cn.Close();
var single = string.Join("", data);
}
Now the issue that I am facing is that I am unable to get all the rows data. The total rows are 9 but I am getting less than that
How can I achieve this? Any help would be highly appreciated.
Looks like those are integer value then you can do something like
List<int> data = new List<int>;
while (reader.Read())
{
data.Add(int.Parse(reader["read_param"].ToString()));
}
Then you can use string.Join() method like
var single = string.Join(",", data);
Based on #Rahul, your code should be:
Your update 1 is different code.
What do you want to achieve here.
List<string> data = new List<string>();
using (MySqlConnection cn = new MySqlConnection(conn.ConnectionString))
{
string query = "SELECT m.`read_param` FROM mdc_request m WHERE m.`row_id` = #row_id";
cn.Open();
MySqlCommand cmd = new MySqlCommand(query, cn);
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#row_id", iterations.row_id);
reader = cmd.ExecuteReader();
while (reader.Read())
{
data.Add(reader["read_param"].ToString());
}
}
var single = string.Join("", data);
I need to insert into a table "pass" or "fail", if from the query done there is a single fail instead of 'RProva' I have to put "fail" if the query can't find a single fail instead of 'RProva' I have to insert "pass", the query is working but I can't figure out how to do the if with the results of a query, maybe I have to use a "for"? Don't know. It is the attempt to make it, the second is the query where I have to insert the result of the possbile "IF"
1.
SqlCommand cmdRD = new SqlCommand("SELECT ResItem AS RD FROM tSE JOIN tL ON tSE.idSE=tL.idL WHERE tL.Selection=1");
var RD = cmdRD.ExecuteScalar();
var values = new List<string>();
using (cmdRD,sqliteCon)
{
using (SqlDataReader reader = cmdRD.ExecuteReader())
{
while (reader.Read())
{
values.Add(reader[0].ToString());
}
}
}
2.
SqlCommand cmd1 = new SqlCommand("INSERT INTO tSD(NomeItem,ResItemDet,DateStartDet,DateEndDet) OUTPUT inserted.Id VALUES (#NI,#RProva,#DATESE,#DATEED)");
cmd1.Parameters.AddWithValue("#DATESE", DATESE);
cmd1.Parameters.AddWithValue("#DATEED", DATEED);
cmd1.Parameters.AddWithValue("#NI", NI);
using (cmd1,sqliteCon)
{
foreach (var value in values)
{
if (value.Equals(pass))
{
cmd1.Parameters.AddWithValue("#RProva", value);
}
else
{
cmd1.Parameters.AddWithValue("#RProva", fail);
}
cmd1.ExecuteNonQuery();
}
}
int generatedId = Convert.ToInt32(cmd1.ExecuteScalar());
cmd1.Parameters.Clear();
SqlCommand cmd2 = new SqlCommand("UPDATE tSE SET FK_TSD_id = #tsdId FROM tL JOIN tSE ON tL.idL = tSE.idSE WHERE tL.Selection=1 ", sqliteCon);
cmd2.Parameters.AddWithValue("#tsdId", generatedId);
cmd2.ExecuteNonQuery();
MessageBox.Show("Dato Aggiunto");
}
sqliteCon.Close();
1.1
SqlCommand cmdRD = new SqlCommand("SELECT ResItem AS RD FROM tSE JOIN tL ON tSE.idSE=tL.idL WHERE tL.Selection=1", sqliteCon);
var RD = cmdRD.ExecuteScalar();
var tot =pass;
using (cmdRD)
{
using (SqlDataReader reader = cmdRD.ExecuteReader())
{
while (reader.Read())
{
if(reader[0].ToString()==fail)
{
tot = fail;
break;
}
}
MessageBox.Show(tot);
}
}
i'm arrived to that(1.1) it works but i've to insert the TOT into RProva
Based on your question and comment I think you misunderstood ExecuteScalar:
ExecuteScalar executes the query, and returns the first column of the first row in the result set returned by the query. learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.executescalar
I dont know the Type of "RD" or "PASS", but the IF in your example (when using ExecuteScalar) seems OK. Else when you are using ExecuteReader you should use some kind of an loop to iterate through the Items. Like this:
string pass = "abc"; // guessing types and values
string fail = "failed";
string sqliteCon = "Data Source=(localdb)\\MSSQLLocalDB;Database=BooksDb";
using (SqlConnection connection = new SqlConnection(sqliteCon))
{
connection.Open();
var queryString = #"SELECT ResItem AS RD
FROM tSE
JOIN tL ON tSE.idSE = tL.idL
WHERE tL.Selection=1";
var values = new List<string>();
using (SqlCommand command = new SqlCommand(queryString, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
values.Add(reader[0].ToString());
}
}
}
var queryInsert = #"INSERT INTO tSD (NomeItem,ResItemDet,DateStartDet,DateEndDet)
VALUES (#NI, #RProva, #DATESE, #DATEED)";
using (SqlCommand command2 = new SqlCommand(queryInsert, connection))
{
foreach(var value in values)
{
command2.Parameters.Clear();
if (value.Equals(pass))
{
command2.Parameters.AddWithValue("#RProva", value);
}
else
{
command2.Parameters.AddWithValue("#RProva", fail);
}
command2.ExecuteNonQuery();
}
}
}
Theres for sure a better way, but maybe this helps you out.
EDIT:
Here is how I would implement your code example:
using (SqlConnection sqliteCon = new SqlConnection(connection))
{
sqliteCon.Open();
var values = new List<string>();
var query = "SELECT ResItem AS RD FROM tSE JOIN tL ON tSE.idSE=tL.idL WHERE tL.Selection=1";
using (SqlCommand cmdRD = new SqlCommand(query, sqliteCon))
{
var RD = cmdRD.ExecuteScalar();
using (SqlDataReader reader = cmdRD.ExecuteReader())
{
while (reader.Read())
{
values.Add(reader[0].ToString());
}
}
}
int generatedId = 0;
var query2 = "INSERT INTO tSD(NomeItem,ResItemDet,DateStartDet,DateEndDet) OUTPUT inserted.Id VALUES (#NI,#RProva,#DATESE,#DATEED)";
using (SqlCommand cmd1 = new SqlCommand(query2, sqliteCon))
{
foreach (var value in values)
{
cmd1.Parameters.Clear();
cmd1.Parameters.AddWithValue("#DATESE", DATESE);
cmd1.Parameters.AddWithValue("#DATEED", DATEED);
cmd1.Parameters.AddWithValue("#NI", NI);
if (value.Equals(pass))
{
cmd1.Parameters.AddWithValue("#RProva", value);
}
else
{
cmd1.Parameters.AddWithValue("#RProva", fail);
}
cmd1.ExecuteNonQuery();
}
generatedId = Convert.ToInt32(cmd1.ExecuteScalar());
}
var query3 = "UPDATE tSE SET FK_TSD_id = #tsdId FROM tL JOIN tSE ON tL.idL = tSE.idSE WHERE tL.Selection=1 ";
using (SqlCommand cmd2 = new SqlCommand(query3, sqliteCon))
{
cmd2.Parameters.AddWithValue("#tsdId", generatedId);
cmd2.ExecuteNonQuery();
}
}
I am having the below code where I am querying the MySQL database. I need to replace my select query to prepare statement
public static void ValidateName(List<Employees> EmpList, string Grp)
{
var connStr = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
string selectQuery;
for (int i = 0; i < EmpList.Count; i++)
{
selectQuery = "Select EmpName from Employee where group = #Grp AND #Name in (FirstName, LastName);";
using (MySqlConnection conn = new MySqlConnection(connStr))
using (MySqlCommand cmd = new MySqlCommand(selectQuery, conn))
{
cmd.Parameters.Add("#Grp", MySqlDbType.VarChar).Value = Grp;
cmd.Parameters.Add("#Name", MySqlDbType.VarChar).Value = EmpList[i].Name;
conn.Open();
var reader = cmd.ExecuteReader();
List<string> lineList = new List<string>();
while (reader.Read())
{
lineList.Add(reader.GetString(0));
}
if (lineList.Count <=0)
{
WriteValidationFailure(EmpList[i], "Name doesnot exists in the DB");
}
conn.Close();
}
}
}
This code works perfectly. But for improvement I need to use the prepare statements instead of the query I am using. Because I am having similar kinds of various validation in my code, I am not sure how to reuse the parameters effectively.
You are very close. Just call cmd.Prepare(), keep references to the parameters, and reuse the command:
public static void ValidateName(List<Employees> EmpList, string Grp)
{
var connStr = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
string selectQuery;
selectQuery = "Select EmpName from Employee where group = #Grp AND #Name in (FirstName, LastName);";
using (MySqlConnection conn = new MySqlConnection(connStr)) {
conn.Open();
using (MySqlCommand cmd = new MySqlCommand(selectQuery, conn))
{
var prmGrp = cmd.Parameters.Add("#Grp", MySqlDbType.VarChar);
var prmName = cmd.Parameters.Add("#Name", MySqlDbType.VarChar);
cmd.Prepare();
for (int i = 0; i < EmpList.Count; i++)
{
prmGrp.Value = Grp;
prmName.Value = EmpList[i].Name;
using (var reader = cmd.ExecuteReader()) {
List<string> lineList = new List<string>();
while (reader.Read())
{
lineList.Add(reader.GetString(0));
}
if (lineList.Count <=0)
{
WriteValidationFailure(EmpList[i], "Name doesnot exists in the DB");
}
}
}
}
conn.Close();
}
}
Working with C# and MySQL here (Visual Studio 12 and MySQL workbench 6.1).
I'm trying to get the entire table into a list.
This is what I have so far:
List<Object> arrList = new List<Object>();
string str = #"server=localhost;database=test;userid=root;password=asd;";
MySqlConnection con = new MySqlConnection(str);
con.Open();
MySqlCommand cmd = new MySqlCommand(query, con);
cmd.CommandText = query;
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
arrList.Add(reader["* "]);
}
When I pass SELECT * FROM emp; for query and try to get a toString of arrList, I get an indexOutOfBounds exception. (My table emp has 1 record in it.)
Thanks!
Edit: I'm trying to get the entire table (sequentially) into a list. Is this the right approach?
Edit 2: What if we don't know the number of columns in the table?
Change to:
while (reader.Read())
{
arrList.Add(reader["myColumnTitle"].ToString());
}
cause "* " isn't a valis columnname. alternative you can use an index
arrList.Add(reader[0].ToString());
for each Column:
List arrList = new List();
string str = #"server=localhost;database=test;userid=root;password=asd;";
string query = "SELECT * FROM emp";
MySqlConnection con = new MySqlConnection(str);
con.Open();
MySqlCommand cmd = new MySqlCommand(query, con);
cmd.CommandText = query;
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
var value = reader[i];
arrList.Add(Convert.ToString(value))
}
}
reader.Read() read your results row by row. That means inside this while statement, you need to read all columns of your query.
When you write "* ", your reader looks for a column named * which you don't have. MySqlDataReader can't understand to read all columns when you write * as you can in an sql query.
This should work.
while (reader.Read())
{
arrList.Add((string)reader[0]);
arrList.Add((string)reader[1]);
}
If you really don't know how many fields that your MySqlDataReader has, you can use SqlDataReader.FieldCount property.
Gets the number of columns in the current row.
So you code can be like;
while (reader.Read())
{
for(int i = 0; i < reader.FieldCount; i++)
{
arrList.Add((string)reader[i]);
}
}
Also use using statement to dispose your database connections and objects like;
using(MySqlConnection con = new MySqlConnection(str))
using(MySqlCommand cmd = con.CreateCommand())
{
...
...
using(MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
for(int i = 0; i < reader.FieldCount; i++)
{
arrList.Add((string)reader[i]);
}
}
}
}
I am doing an sql select statement on my web service in Visual Studio 2010. It is only from a column but there are multiple rows of data. How do I populate an arraylist with the data and return it?
[WebMethod]
public List<String> getAccType(string bankId)
{
myConnection.Open();
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand("SELECT TypeName FROM AccType where BankID = '" + bankId + "'", myConnection);
myReader = myCommand.ExecuteReader();
List<String> AccType = new List<string>();
while (myReader.Read())
{
string iAccType = myReader["TypeName"].ToString();
AccType.Add(iAccType);
}
return AccType;
}
}
While you could return an ArrayList, it would be better to return a strongly-typed collection, either a List<T> or IEnumerable<T> with an underlying List<T> collection, perhaps.
Here is an example using a SqlDataReader to extract data from a column and populate such a list. Note: I haven't included any error handling.
public IEnumerable<int> GetOrderIds()
{
var ids = new List<int>();
var queryString = "SELECT OrderID FROM dbo.Orders;";
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(queryString, connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var id = reader.GetInt32(0);
ids.Add(id);
}
}
}
return ids;
}