I currently accessing a database using multiple queries and storing the results from the queries into DatatTables. I decided since I'm using multiple DataTables to store them inside a DataSet.
I can see that data is inside the DataTables when I print them out. However when I try to access them from the DataSet to print out the data, I get nothing back; it is empty.
string querytest1 = "SELECT * FROM test1";
string querytest2 = "SELECT * FROM test2";
string querytest3 = "SELECT * FROM test3";
using(OleDbConnection connection = new OleDbConnection(connectionString)){
OleDbCommand commandtest1 = new OleDbCommand(querytest1 , connection);
OleDbCommand commandtest2 = new OleDbCommand(querytest2 , connection);
OleDbCommand commandtest3 = new OleDbCommand(querytest3 , connection);
connection.Open();
DataSet dataSet = new DataSet();
OleDbDataAdapter dataAdaptertest1 = new OleDbDataAdapter(commandResults);
OleDbDataAdapter dataAdaptertest2 = new OleDbDataAdapter(commandResults);
OleDbDataAdapter dataAdaptertest3 = new OleDbDataAdapter(commandProjects);
DataTable dataTabletest1 = new DataTable();
DataTable dataTabletest2 = new DataTable();
DataTable dataTabletest3 = new DataTable();
dataAdaptertest1.Fill(dataTabletest1 );
dataAdaptertest2.Fill(dataTabletest2 );
dataAdaptertest3.Fill(dataTabletest3 );
dataTabletest1 = dataSet.Tables.Add("test1 ");
dataTabletest2 = dataSet.Tables.Add("test2 ");
dataTabletest3 = dataSet.Tables.Add("test3 ");
Console.WriteLine("DataSet has {0} DataTables \n", dataSet.Tables.Count);
foreach (DataTable objDt in dataSet.Tables)
Console.WriteLine("{0}", objDt.TableName);
return dataSet;
Expected behaviour: is to be able to access a DataTable from the DataSet and print out the data.
Example: Print out the contents in Test1
The code is redundant. I just don't know a better way to do this.
You don't need three adapters to fill a DataSet with the results from three commands.
You can simply write:
string query1 = "SELECT * FROM test1";
string query2 = "SELECT * FROM test2";
string query3 = "SELECT * FROM test3";
DataSet dataSet = new DataSet();
using(OleDbConnection connection = new OleDbConnection(connectionString)){
connection.Open();
OleDbCommand cmd = new OleDbCommand(q1, connection);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(ds, "Test1");
cmd.CommandText = q2;
da = new OleDbDataAdapter(cmd);
da.Fill(ds, "Test2");
cmd.CommandText = q3;
da = new OleDbDataAdapter(cmd);
da.Fill(ds, "Test3");
}
Console.WriteLine("DataSet has {0} DataTables \n", ds.Tables.Count);
foreach (DataTable objDt in ds.Tables)
Console.WriteLine("{0}", objDt.TableName);
The trick is filling the same DataSet three times instead of three different DataTables and giving at each fill a different name for each table created.
But, don't you see that dataSet.Tables.Add() call actually creates new DataTable instance, and trying to set its TableName property to "test1 " (btw. take care, space is not allowed in TableName).
That newly created instance(s) are set to properties dataTabletest1...3 - so, you lose access to the original ones, initially populated with data from the database.
You should do something like this:
DataTable dataTabletest1 = dataSet.Tables.Add("Test1");
DataTable dataTabletest2 = dataSet.Tables.Add("Test2");
DataTable dataTabletest3 = dataSet.Tables.Add("Test3");
dataAdaptertest1.Fill(dataTabletest1);
dataAdaptertest2.Fill(dataTabletest2);
dataAdaptertest3.Fill(dataTabletest3);
Please, check: https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/dataset-datatable-dataview/adding-a-datatable-to-a-dataset
Related
I am creating an application in which I am getting some data in my dataGridView1 in my form. I want to access my last row of data in some variables like I want to store columns in variables and use them. I know how to do this in GridView Cell click event but I want to use this in a loop like after every 10 seconds new data comes from database to dataGridView1 and I want last row to be accessed in variables.
Below is the code of how I am loading data in dataGridView
using (var con = new SqlConnection(ConStr))
{
string query = "SELECT * FROM CHECKINOUT";
using (var cmd = new SqlCommand(query, con))
{
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0].DefaultView;
}
}
Can you not just access the last row of Table 0 in your dataset and then assign all columns to variables
int lastRow = 0;
lastRow = ds.Tables(0).rows.count - 1;
string col1 = ds.Tables(0).Rows(lastRow)(0).tostring.trim;
Using your code you could do:
using (var con = new SqlConnection(ConStr))
{
string query = "SELECT * FROM CHECKINOUT";
using (var cmd = new SqlCommand(query, con))
{
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0].DefaultView;
}
}
int lastRow = 0;
lastRow = ds.Tables(0).rows.count - 1;
string col1 = ds.Tables(0).Rows(lastRow)(0).tostring.trim;
string col2 = ds.Tables(0).Rows(lastRow)(1).tostring.trim;
string col3 = ds.Tables(0).Rows(lastRow)(2).tostring.trim;
I have a dataset which contains two tables. Table[0] gets filled with multiple rows. I then need to iterate those rows and for each row run another query and fill those results to Table[1]. What is the correct way to fill a dataset with multiple rows within a loop? Abbreviated code sample of where I am:
DataSet ds = new DataSet();
sql = myquery1;
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
da.Fill(ds, "Products");
foreach (DataRow dr in ds.Tables[0].Rows)
{
productID = ds.Tables[0].Rows[0]["ProductID"].ToString();
if (productID != String.Empty)
{
sql = String.Empty;
sql = myquery2 where productID = 'xxxxx'
da = new SqlDataAdapter(sql, conn);
da.Fill(ds, "ProductProperties");
}
}
This fills the "ProductProperties" datatable on the first loop but doesn't add future results. What's the right way to keep adding multiple result sets to the datatable?
You're going about this the wrong way. You only need one query to populate the child table. E.g.
Dim ds As New DataSet
Using connection As New SqlConnection("connection string here"),
parentAdapter As New SqlDataAdapter("SELECT * FROM ParentTable",
connection),
childAdapter As New SqlDataAdapter("SELECT * FROM ChildTable WHERE ParentID IN (SELECT ParentID FROM ParentTable)",
connection)
connection.Open()
parentAdapter.Fill(ds, "Parent")
parentAdapter.Fill(ds, "Child")
End Using
All you need to do is duplicate the parent query as the subquery for the child table. You can even put both queries inside one data adapter if you want. The point is that there's no need to loop through the parent records and execute a separate query for each one.
You query should return two record sets
SELECT ProductId, Name
FROM Products
SELECT ProductId, Property1, Property2
FROM ProductProperties
Then you can read the data from the above query to a DataSet as follows. So you will get two tables in the DataSet with the results from the two records sets from the above query
using (SqlConnection con = new System.Data.SqlClient.SqlConnection(connString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "query";
cmd.Connection = con;
con.Open();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds);
con.Close();
}
}
I currently have a working query for the first element in the array of ID's as seen below. What I need to do is add a for loop so I rerun the query for every element in the array and add each new row to the datatable but I am not sure how I do this? Unless there is a way I can include all ID's of my array in the where clause so I retrieve all rows through first run.
PID[] is a string array and could have anywhere from 1 to 5 elements that are random ID's.
Any help would be appreciated!
for loop here?
string firstQuery = "select * from Property p " +
"where p.id in (#pID)";
connString.Open();
SqlCommand selectAll = new SqlCommand(firstQuery, connString);
selectAll.Parameters.AddWithValue("#pID", PID[0]);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = selectAll;
DataSet ds = new DataSet();
adapter.Fill(ds);
connString.Close();
DataTable table = ds.Tables[0];
Yes you can include all ids in one parameter and get results that match them:
var parameters = new string[PID.Length];
var selectAll = new SqlCommand();
for (int i = 0; i < PID.Length; i++)
{
parameters[i] = string.Format("#Age{0}", i);
selectAll .Parameters.AddWithValue(parameters[i], PID[i]);
}
selectAll.CommandText = string.Format("SELECT * from Property p WHERE p.id IN ({0})", string.Join(", ", parameters));
selectAll.Connection = connString;
connString.Open();
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = selectAll;
DataSet ds = new DataSet();
adapter.Fill(ds);
connString.Close();
DataTable table = ds.Tables[0];
my command is something like this:
string command = "SELECT * FROM [SheetName1$]; SELECT * FROM [SheetName2$]; ...."
When I do
DataSet set = new DataSet();
using(OleDbDataAdapter adapter = new OleDbDataAdapter(command, connection))
{
adapter.Fill(ds)
}
I end up with an empty DataSet (more specifically I end up with an exception that says Characters found after end of SQL statement). However, if I use only one SELECT query this works fine.
Excel cannot execute more than in one statement. Try making this in two commands.
DataSet set1 = new DataSet();
using(OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [SheetName1$];", connection))
{
adapter.Fill(set1 );
}
DataSet set2 = new DataSet();
using(OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [SheetName2$];", connection))
{
adapter.Fill(set2);
}
Instead of filling in DataSets, fill DataTables and then add said DataTables to a DataSet.
DataSet ds = new DataSet();
DataTable dt1 = ds.Tables.Add("set1");
using(OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [SheetName1$];", connection))
{
adapter.Fill(dt1);
}
DataTable dt2 = ds.Tables.Add("set2");
using(OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [SheetName2$];", connection))
{
adapter.Fill(dt2);
}
can try this in SQL query:
SELECT * FROM [SheetName1$]
UNION ALL
SELECT * FROM [SheetName2$]
I hope this would help
I know there are questions like this already, but I've combined all the common code to the answers and still am getting no success, so here I am.
Here's the deal. I have a block of code using SqlDataAdapter.Update to insert new rows into an existing table...
string command = "SELECT * FROM " + tableName;
// Initialize connection
if (oConn == null)
{
oConn = new SqlConnection(mainConnStr);
}
sCmd = new SqlCommand(command, oConn);
sCmd.CommandText = command;
SqlDataAdapter sDA = new SqlDataAdapter(sCmd);
DataSet ds = new DataSet();
oConn.Open();
sDA.Fill(ds, tableName);
oConn.Close();
DataTable dt = ds.Tables[tableName];
//Add each row.
for (int i = 0; i < queryResult.Rows.Count; i++)
{
dt.ImportRow(queryResult.Rows[i]);
}
// Handle the command building for the table update.
SqlCommandBuilder sCB = new SqlCommandBuilder(sDA);
oConn.Open();
sDA.Update(ds, tableName);
oConn.Close();
As mentioned, this works fine. However, if I try very similar code with a two-column test table (testInt, an int non-null; and testSTring, a varchar(50), null-allowed)...
private static void Main(string[] args)
{
SqlConnection = /* Build connection */
string sqlQuery = "SELECT * FROM TestTable WHERE 0 = 1";
SqlDataAdapter sDA = new SqlDataAdapter(sqlQuery, conn);
DataSet dataSet = new DataSet();
conn.Open();
sDA.Fill(dataSet);
conn.Close();
DataRow newRow = dataSet.Tables[0].NewRow();
newRow["testInt"] = 12;
SqlCommandBuilder cb = new SqlCommandBuilder(sDA);
conn.Open();
sDA.Update(dataSet);
conn.Close();
}
This code does nothing, and I can't figure out what in the world the difference is. (I should note that I've also tried using ImportRow instead of the NewRow technique.) Even when I try this block of code with the same tables as the first block (the working block), it still won't update the data.
Therefore, my question is: What fine details must be accounted for when using SqlDataAdapter.Update?
Thanks.
-F
You have to add the row to the DataSet
DataRow newRow = dataSet.Tables[0].NewRow(); // this doesn't add a new row to the data set
dataSet.Tables[0].Rows.Add(newRow); // you have to call this after