After an hour of debugging I am trying to find why my Query returns only 1 ID where there are at least 3:
public static string[] selectAGIdOfKC(string id)
{
int nbAg = 0;
DataTable results = new DataTable();
using (OleDbConnection conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=bdd.mdb;
Persist Security Info=False;"))
{
OleDbCommand cmd = new OleDbCommand("SELECT Id FROM ActionG WHERE Num_Kc = #Id", conn);
conn.Open();
cmd.Parameters.AddWithValue("#Id", id);
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
conn.Close();
adapter.Fill(results);
nbAg=results.Rows[0].ItemArray.Count();
}
string[] myTab = new string[nbAg];
for (int i = 0; i < nbAg; i++)
{
myTab[i] = results.Rows[0].ItemArray[i].ToString();
}
return myTab;
}
I tried to use some workarounds but nothing solves the problem of the missing returned IDs...
Can anyone help me ? Thanks for your time!
It all depends on how you want the results, but assuming that you want nbAg to contain the number of rows returned, and assuming that you want myTab to contain the id-values returned, your code is not written to do what you want.
Please note the ellipsis ... - I have only modified the code that was causing your current symptoms.
public static string[] selectAGIdOfKC(string id)
{
int nbAg = 0;
...
nbAg = results.Rows.Count();
string[] myTab = new string[nbAg];
for (int i = 0; i < nbAg; i++)
{
myTab[i] = results.Rows[i][0].ToString();
// This is the first column of row i
}
return myTab;
}
Related
I am trying to sort a datatable into a DataSet. I want to sort by the Status Column in "DESC". But I am not aware how to go about this. I have tried the suggested solutions online but I seem not to be doing something right. Here is what I have tried, albeit, I have commented out the sorting lines of the code as they do not work for me. How can I sort my table using the Status column in Desc?
[WebMethod(EnableSession = true)]
public List < TaskListClass > getTasks() {
var userId = Session["UserId"].ToString();
List < TaskListClass > objB = new List < TaskListClass > ();
try {
using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConnString"].ToString())) {
connection.Open();
DataSet Myds = new DataSet();
// Myds.Tables[0].DefaultView.Sort = "Status desc";
SqlDataAdapter sqldr = new SqlDataAdapter();
string ProcName = "getTasks";
SqlCommand cmd = new SqlCommand(ProcName, connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#userId", SqlDbType.VarChar, 900).Value = userId;
sqldr.SelectCommand = cmd;
sqldr.Fill(Myds);
DataTable dt = Myds.Tables[0];
// DataTable dt = Myds.Tables[0].DefaultView.ToTable();
for (int i = 0; i < dt.Rows.Count; i++) {
objB.Add(new TaskListClass() {
Id = Convert.ToString(dt.Rows[i]["Id"]),
Subject = Convert.ToString(dt.Rows[i]["Subject"]),
Customer = Convert.ToString(dt.Rows[i]["Customer"]),
Sender = Convert.ToString(dt.Rows[i]["Sender"]),
Receiver = Convert.ToString(dt.Rows[i]["Receiver"]),
Priority = Convert.ToString(dt.Rows[i]["Priority"]),
StartDate = Convert.ToString(dt.Rows[i]["StartDate"]),
EndDate = Convert.ToString(dt.Rows[i]["EndDate"]),
Status = Convert.ToString(dt.Rows[i]["Status"]),
OnProgress = Convert.ToString(dt.Rows[i]["OnProgress"]),
});
}
}
} catch (Exception e) {
msg = e.ToString();
}
return objB;
}
Ok, a few things.
first up, a dataset is a collection of tables - "many tables" possible.
But you have ONE table, so why use a dataset? I see no need. Just use a single data table for this.
And this will reduce the code.
So, I suggest this, or close to this:
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConnString"].ToString()))
{
using (var cmd = new SqlCommand("getTasks", connection))
{
connection.Open();
cmd.CommandType = CommandType.StoredProcedure;
DataTable dt = new DataTable();
cmd.Parameters.Add("#userId", SqlDbType.VarChar).Value = userId;
dt.Load(cmd.ExecuteReader());
// now sort the datatable
dt.DefaultView.Sort = "Status DESC";
// now fill out our object with each row
foreach (DataRow OneRow in dt.Rows)
{
objB.Add(new TaskListClass()
{
Id = OneRow["Id"].ToString(),
Subject = OneRow["Subject"].ToString(),
Customer = OneRow["Customer"].ToString(),
Sender = OneRow["Sender"].ToString(),
Receiver = OneRow["Receiver"].ToString(),
Priority = OneRow["Priority"].ToString(),
StartDate = OneRow["StartDate"].ToString(),
EndDate = OneRow["EndDate"].ToString(),
Status = OneRow["Status"].ToString(),
OnProgress = OneRow["OnProgress"].ToString(),
}); ;
}
}
}
}
return objB;
The way the current code is written, you could add this after the for-loop:
objB = objB.OrderByDescending(t => t.Status).ToList();
Depending of the datatype of Status, it might be sorted alphabetically.
var dataRow = dt.AsEnumerable().OrderByDescending(x => x.Field<string>("Status")).ToList();
foreach (var item in dataRow)
{
//Enter your Code Here
}
Here dt is your datatable.
dataRow is a set of list.
After get the data list, you can asign it to your "objB".
I am having a hard time getting the codes that I need.
The code that I have created can get ALL the column names that I have listed regardless of having a value or not. What I only wanted to happen was to get the column names that has value(1).
I have this code:
internal static List<string> GetAllRoleTypeFromDatabase()
{
List<string> rolelist = new List<string>();
using (var con = new SQLiteConnection(sqliteConnectionMain.connectionString))
using (var cmd = new SQLiteCommand(con))
{
con.Open();
var _command = con.CreateCommand();
var queryq = string.Format("SELECT * FROM tblUserRoleAccess");
string commandText = queryq;
String sSQL;
sSQL = "SELECT * from tblUserRoleAccess";
cmd.CommandText = sSQL;
var dr = cmd.ExecuteReader();
for (var i = 1; i < dr.FieldCount; i++)
{
if (dr != null)
{
rolelist.Add(dr.GetName(i));
}
}
con.Close();
}
return rolelist;
}
Read a line in the reader (as i understand, there's only one row as a result).
For each column in the row check if its value is 1 (I used int, you should use the real type i.e. bool, string ...):
dr.Read();
for (var i = 1; i < dr.FieldCount; i++)
{
if (dr.GetFieldValue<int>(i) == 1)
{
rolelist.Add(dr.GetName(i));
}
}
Here is my code:
private List<string> readFromDatabase()
{
SQLiteConnection m_dbConnection = new SQLiteConnection("Data Source=" + fileName + ".sqlite;Version=3;");
string sql = "SELECT * FROM formsData";
m_dbConnection.Open();
SQLiteDataReader dr = DatabaseHandler.ExecuteCommandReader(sql, m_dbConnection);
List<string> tempList = new List<string>();
if(dr.HasRows)
{
while (dr.Read())
{
tempList.Add(Convert.ToString(dr["fieldName"]));
tempList.Add(Convert.ToString(dr["dataType"]));
tempList.Add(Convert.ToString(dr["numberOfCharacters"]));
}
}
return tempList;
}
I am trying to make it add each value from the database into the list, however it is only adding the last value found, from the final column. Does anyone know how to solve this? Thank you...
you can use a DataTable instead of DataReader (even though its possible to achieve the same result with DataReader).
please check that discussion: Why is DataTable faster than DataReader.
also its a better practice to use Try-Catchsteatments when connecting to databases.
here is an example (based on your code) how to achieve that task usingDataTable:
private List<string> readFromDatabase()
{
DataTable dt = PullData();
List<string> tempList = new List<string>();
if (dt != null & dt.Rows.Count >0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
tempList.Add(Convert.ToString(dt.Rows[i]["fieldName"]));
tempList.Add(Convert.ToString(dt.Rows[i]["dataType"]));
tempList.Add(Convert.ToString(dt.Rows[i]["numberOfCharacters"]));
}
}
return tempList;
}
public DataTable PullData()
{
try
{
string connString = #"your connection string here";
string query = "select * from table";
DataTable dataTable = new DataTable();
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
conn.Close();
da.Dispose();
return dataTable;
}
catch (Exception ex)
{
return null;
}
}
Make sure your record set is positioned at the first row before you start iterating through it.
Also, do you really want to take all the rows of the table and have them as sequential values in a list? Perhaps adding them to class might make more sense.
public class Record{
public string Name { get; set; }
public string Type { get; set; }
public int Size { get; set; }
}
Service class
public string[] loadSecretQues(string email)
{
string[] ques= new string[3];
dbConn = new OdbcConnection(dbConnString);
dbConn.Open();
cmd = new OdbcCommand();
cmd.Connection = dbConn;
cmd = new OdbcCommand("SELECT q1, q2, q3 FROM Information WHERE EmailAdd = '" + email + "'", dbConn);
dRead = cmd.ExecuteReader();
while (dRead.Read())
{
if (dRead.HasRows)
{
for (int i = 1; i <= 3; i++)
{
for (int j = 0; j <= 3; j++)
{
ques[j] = dRead["q" + i].ToString();
}
return ques[i];
}
}
}
}
Page.aspx
protected void btnCheck_Click(object sender, EventArgs e)
{
cmbQues.Items.Add(srvc.loadSecretQues(txtEmail.Text));
}
Good day guys. I am seeking for help. I want to return array values from a function inside a class. The process is, I want to retrieve 3 questions (which are string data type) from my database and store it in a combobox. Any suggestions how to retrieve those three questions? Any other ways? Thanks in advance! :)
You are returning from an inner loop so that rest of iterations ware cancelled, and also you miss to Dispose the command as well as close the open connection. so i suggest you to dispose the command as well as the connection before return, hence the code will be like the following:
no need to check dvc_mst_tdeposit, because if it has no rows control
comes out from while. no need for the outer for Loop(i loop) since
(j Loop is enough to handle this scenario.
dRead = cmd.ExecuteReader();
while (dRead.Read())
{
for (int j = 0; j < 3; j++)
{
ques[j] = dRead["q" + i].ToString();
}
}
dRead.Close();
cmd.Dispose();
dbConn.Close();
return ques;
Use List instead of string array.check the link for advantage
public List<string> loadSecretQues(string email)
{
List<string> ques=new List<string>();
dbConn = new OdbcConnection(dbConnString);
dbConn.Open();
cmd = new OdbcCommand();
cmd.Connection = dbConn;
cmd = new OdbcCommand("SELECT q1, q2, q3 FROM Information WHERE EmailAdd = '" + email + "'", dbConn);
dRead = cmd.ExecuteReader();
if (dRead.HasRows)
{
while (dRead.Read())
{
ques.Add(dRead["yourColumnName"].ToString());
}
}
return ques;
}
I want to read a relatively large table from an MDB file and save its fields to a Dictionary. This is a one time operation and I will not need to UPDATE or INSERT INTO database after that. So I only need a SELECT query.
What is the fastest way to do this. Using Datasets seems slow:
var con = new OleDbConnection();
const string dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;";
const string dbSource = "Data Source = D:/programming/Frames.mdb";
con.ConnectionString = dbProvider + dbSource;
con.Open();
const string query = "SELECT * FROM [Concrete Design 1 - Column Summary Data - ACI 318-99]";
var dt = new DataTable();
var da = new OleDbDataAdapter(query, con);
da.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++)
{
// Create Dictionary here
}
I know using the below method will be faster but I just don't know how to get it right:
var con = new OleDbConnection();
const string dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;";
const string dbSource = "Data Source = D:/programming/Frames.mdb";
con.ConnectionString = dbProvider + dbSource;
var cmd = new OleDbCommand { Connection = con };
con.Open();
cmd.CommandText = "SELECT * FROM [Concrete Design 1 - Column Summary Data - ACI 318-99]";
// I don't know how get the fields and rows from the database
con.Close();
Probably the most efficient approach is using a DataReader to stream the data into the Dictionary. You can use DataReader.FieldCount to get the number of fields.
Here is an example using a custom class that holds all fields:
var dict = new Dictionary<object, Record>();
using(var reader = cmd.ExecuteReader())
{
while(reader.Read())
{
object key = reader[0];
Record rec = new Record(key);
for(int i=0; i< reader.FieldCount; i++)
{
rec.Fields.Add(reader[i]);
}
dict.Add(key, rec);
}
}
Here's the class, use the correct types and multiple properties instead of the list if possible:
public class Record
{
public Record(object key)
{
this.Key = key;
Fields = new List<object>();
}
public object Key;
public List<object> Fields;
}
I think you should check if a datareader with a loop while reader read is faster to add item to your dictionnary.