mysql selecting with join to dataset and datatable in c# - c#

I searched a lot but could not find the right solution.
Lets say ill select data like:
using(MySqlConnection connection = new MySqlConnection(MyConnectionString))
using(MySqlCommand cmd = connection.CreateCommand())
{
connection.Open();
cmd.CommandText = "SELECT a.Id, a.Foo, b.Bar FROM tableA a, tableB b where a.Id = b.Id";
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
DataTable dt = ds.Tables[...]; //<== here is the problem
}
and I want to add this to a datatable,
How do I call the table in this case ?
Is it tableA ?
Does it matters how I name it ? (could I name it foobar as well???)

It is unclear what you are really asking for, but due to the length of comment and clarification, putting into an answer.
If you are trying to get multiple query results back from MySQL into a single "DataSet" (which can contain multiple tables), your query could contain multiple sql-statements and each would be returned into the dataset for you as different table results. For example, if you did something like...
using(MySqlConnection connection = new MySqlConnection(MyConnectionString))
using(MySqlCommand cmd = connection.CreateCommand())
{
connection.Open();
cmd.CommandText =
#"select * from TableA;
select * from TableB;
SELECT a.Id, a.Foo, b.Bar FROM tableA a, tableB b where a.Id = b.Id;";
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
}
Your dataset would have 3 tables in it in direct correlation of the queries provided..
ds.Tables[0] = result of tableA all records.
ds.Tables[1] = result of tableB all records.
ds.Tables[2] = result of JOIN query tableA and tableB.
you could then refer to them locally however you need to...
ds.Tables[0].TableName = "anyLocalTableNameReference".
var t1Recs = ds.Tables[0].Rows.Count;
etc... or even create your own individual datatable variable name without having to explicitly reference the dataset and table array reference
DataTable myLocalTableA = ds.Tables[0];
DataTable myLocalTableB = ds.Tables[1];
DataTable myJoinResult = ds.Tables[2];
Hopefully this clarifies a bunch with the querying and referencing of multiple data results returned and how to then reference to the tables individually.

Related

Visual C#, SQL query from an existing DataTable?

Say if I populate a DataTable with a SQL command like this:
SQLCmd.Parameters.AddWithValue("#Date",DateTime.Today());
SQLCmd.CommandText = #"select ID, Name, Date from TestTable1 where Date=#Date";
SqlDataAdapter SQLAdapter = new SqlDataAdapter(SQLCmd);
DataTable dt = new DataTable();
SQLAdapter.Fill(dt);
Is it possible do a further query looking for something in another table which is also in dt?
For example, do something like
select ID
from TestTable2
where TestTable2.ID = dt["ID"];
Something like that... assuming both TestTable1 and TestTable2 have a column ID.
Thanks for helping!
You could use linkserver to get the data at a time or else below code may help you out. Get all the IDs with "," separated and passed it to second query.
string ids = String.Join(",", dt.AsEnumerable().Select(x => x.Field<int>("ID").ToString()).ToArray());
SQLCmd.Parameters.AddWithValue("#ID",ids);
SQLCmd.CommandText = #"select ID from TestTable2 where ID in ("+#ID+")";
SqlDataAdapter SQLAdapter = new SqlDataAdapter(SQLCmd);
DataTable dt2 = new DataTable();
SQLAdapter.Fill(dt2);
Just as an alternative option to think about, you could JOIN TestTable2 like:
SELECT t1.[ID]
,t1.[Name]
,t1.[DATE]
,t2.[ID]
FROM TestTable1 t1
INNER JOIN TestTable2 t2 ON t1.ID = t2.ID
WHERE t1.[DATE] = #Date
You can filter using DataView
DataView dv = new DataView(dt);
dv.RowFilter = "query"; // query example = "DATE = 'Your Date'"

Create Table or DataSet from relation between 2 Tables in same DataSet

I've been stuck on this all day.... My love to the person who can solve it!!!!
So, there are 2 Tables
Access Table in (ds.Tables["Access"]) which contains columns of
Barcode, Description, quantity in warehouse etc
and Excel Table in (ds.Tables["Excel"]) which contains columns of
Barcode, quantiy ordered etc however named F2,F4,F8
So how do I get a final DataTable/DataSet (anything that I can .DataSource to on DataGridView) with Excel and Access matched on Barcode????
OleDbConnection conAccess = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\PROGRAMMING.LAB\\geekx_recent.mdb");
OleDbDataAdapter daAccess = new OleDbDataAdapter("Select Barcode AS BARCODE, quantity AS QTY_WH From Stock", conAccess);
DataSet dsAll = new DataSet();
daAccess.Fill(dsAll, "Access");
OleDbConnection conExcel = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\PROGRAMMING.LAB\\order.xlsx;Extended Properties = Excel 12.0 Xml");
OleDbDataAdapter daExcel = new OleDbDataAdapter("SELECT F2 AS BARCODE, F8 AS ORDER_CUST FROM [phil$] WHERE ISNUMERIC(F8)",conExcel);
daExcel.Fill(dsAll, "Excel");
DataRelation dr = dsAll.Relations.Add("Excel_Access", dsAll.Tables["Excel"].Columns["BARCODE"], dsAll.Tables["Access"].Columns["BARCODE"], false);
DataTable dtExcel = dsAll.Tables["Excel"];
DataTable dtAccess = dsAll.Tables["Access"];
DataTable dtAll = new DataTable();
var query = from ex in dtExcel.AsEnumerable()
join ac in dtAccess.AsEnumerable()
on ex.Field<string>("BARCODE") equals ac.Field<string>("BARCODE")
select new
{
Order = ex.Field<string>("ORDER_CUST"),
Stock = ac.Field<string>("QTY_WH"),
Barcode = ex.Field<string>("BARCODE")
};
foreach (var q in query)
{
dtAll.Rows.Add(q.Barcode, q.Stock, q.Order);
}
dataGridView1.DataSource = dtAll;
This returns
An unhandled exception of type 'System.InvalidCastException' occurred in System.Data.DataSetExtensions.dll
Additional information: Unable to cast object of type 'System.Double' to type 'System.String'.
At the select new block
Any ideas anyone?
See code below and following webpage for joining tables : https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
DataTable dt1 = new DataTable();
DataTable dt2 = new DataTable();
var results =
from c1 in dt1.AsEnumerable()
join c2 in dt2.AsEnumerable()
on c1.Field<int>("ID") equals c2.Field<int>("ID") into cs
select new { Category = c1.Field<string>("ColB"), Fields = cs };

Merging two tables using datasets and display in gridview

I have these two tables
Table One
CODE TITLE
KANT-015 How to Build a Brand
KANT-016 Avoiding the Workforce Crisis
KANT-017 Creating Winning Social Media Strategies
KANT-028 Be Prepared to Lead
KANT-029 The Values-Based Leader
Table Two
CODE
KANT-015
KANT-016
KANT-017
KANT-028
KANT-029
How can I merge them in one dataset to dosplay them in one grid view
This is what I have done so far
conn = new OleDbConnection(#"Provider=Microsoft.Jet.OleDb.4.0;
Data Source =" + Server.MapPath("App_Data\\LR Product Database 2000.mdb"));
conn.Open();
setOleDb = new DataSet();
OleDbDataAdapter dbaOle = new OleDbDataAdapter("SELECT * FROM tblProducts", conn);
dbaOle.Fill(setOleDb);
sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["LRVWebsite"].ToString());
sqlCon.Open();
dsSql = new DataSet();
SqlDataAdapter dba = new SqlDataAdapter(#"SELECT C.CustomerFirstName,C.CustomerLastName, C.CustomerCompany,C.CustomerPosition,C.CustomerCountry,C.CustomerProvince,C.CustomerContact,CP.ActionDate,CP.ProductCode,CP.CustomerEmail FROM tblCustomers C INNER JOIN tblCustomerProducts CP ON C.CustomerEmail = CP.CustomerEmail ORDER BY ActionDate DESC", connString);
//#"SELECT C.CustomerFirstName,C.CustomerLastName,C.CustomerCompany,C.CustomerPosition,C.CustomerCountry,C.CustomerProvince,C.CustomerContact,CP.ActionDate,CP.ProductCode,CP.CustomerEmail FROM tblCustomers C INNER JOIN tblCustomerProducts CP ON C.CustomerEmail = CP.CustomerEmail ORDER BY ActionDate DESC", connString);
dba.Fill(dsSql);
dsSql.Merge(setOleDb);
GridView1.DataSource = dsSql;
GridView1.DataBind();
sqlCon.Close();
You're missing a PK, the merge happens on a PK.
Set one on both tables:
setOleDb.Tables[0].PrimaryKey = setOleDb.Tables[0].Columns["CODE"];

access 2007 query and c# datatable show different output

I have the below query in access 2007 which gave me correct results using the sql design view of access..
SELECT B1.LAYER_TYPE,
B1.LAYER_NAME AS LAYER_NAME,
B2.LAYER_NAME AS RELATED_LAYER_NAME,
B3.LAYER_NAME AS RELATED_LAYER2_NAME,
C.RULE_NAME
FROM (((NCS_RULES_RELATIONS AS A
LEFT JOIN NCS_LAYERS AS B1 ON A.LAYER_ID = B1.LAYER_ID)
LEFT JOIN NCS_LAYERS AS B2 ON A.RELTD_LAYER_ID = B2.LAYER_ID)
LEFT JOIN NCS_LAYERS AS B3 ON A.RELTD_LAYER2_ID = B3.LAYER_ID)
LEFT JOIN NCS_RULES AS C ON A.RULE_ID = C.RULE_ID
ORDER BY B1.LAYER_TYPE;
the results are below :
but when i try to get the results to a datatable using c# and oledbconnection to access, the RULE_NAME field value for the last row shows weird results(see pic below).
my code for retrieving table is below:
public DataTable GetTable(string strSelectSQL)
{
if (this.con.State != ConnectionState.Open)
con.Open();
DataTable dt = new DataTable();
DataSet ds = new DataSet();
IDbCommand command = con.CreateCommand();
command.CommandText = strSelectSQL;
command.Connection = con;
IDbDataAdapter da = factory.CreateDataAdapter();
da.SelectCommand = command;
da.Fill(ds);
dt = ds.Tables[0];
con.Close();
return dt;
}
can somebody help me with this strange behavior?
Seems everything is fine. My guess you have multiline value in Rule_name field like this: AnnoFromLine\n\rDimOnLine. Datagridview displaying multiline value as you can see and sql design view diplaying just first line.

Using SqlDataAdapter to insert a row

I want to insert a row into the Database using SqlDataAdapter. I've 2 tables (Custormers & Orders) in CustomerOrders database and has more than thousand records. I want to create a GUI (TextBoxes) for adding new customer & orders into the Database to their respective tables.
How should I do it?
I guess the method that is usually followed is
dataAdapter = new SqlDataAdapter (sqlQuery, conn);
dataSet = new DataSet();
da.Fill(dataSet);
Now take the values from textboxes (or use DataBinding) to add a new row into the dataSet and call
da.Update(dataSet);
But the Question is Why should I fetch all other records into dataSet using da.Fill(dataSet ) in the first place? I just want to add a single new record.
For this purpose what I'm doing is, Creating the schema of the Database in the DataSet. like this:
DataSet customerOrders = new DataSet("CustomerOrders");
DataTable customers = customerOrders.Tables.Add("Customers");
DataTable orders = customerOrders.Tables.Add("Orders");
customers.Columns.Add("CustomerID", Type.GetType("System.Int32"));
customers.Columns.Add("FirstName", Type.GetType("System.String"));
customers.Columns.Add("LastName", Type.GetType("System.String"));
customers.Columns.Add("Phone", Type.GetType("System.String"));
customers.Columns.Add("Email", Type.GetType("System.String"));
orders.Columns.Add("CustomerID", Type.GetType("System.Int32"));
orders.Columns.Add("OrderID", Type.GetType("System.Int32"));
orders.Columns.Add("OrderAmount", Type.GetType("System.Double"));
orders.Columns.Add("OrderDate", Type.GetType("System.DateTime"));
customerOrders.Relations.Add("Cust_Order_Rel", customerOrders.Tables["Customers"].Columns["CustomerID"], customerOrders.Tables["Orders"].Columns["CustomerID"]);
I used DataBinding to bind these columns to respective text boxes.
Now I'm confused! What should I do next? How to use Insert command? Because I didn't give any dataAdapter.SelectCommand so dataAdapter.Update() wont work I guess. Please suggest a correct approach.
Set the select command with a "0 = 1" filter and use an SqlCommandBuilder so that the insert command is automatically generated for you.
var sqlQuery = "select * from Customers where 0 = 1";
dataAdapter = new SqlDataAdapter(sqlQuery, conn);
dataSet = new DataSet();
dataAdapter.Fill(dataSet);
var newRow = dataSet.Tables["Customers"].NewRow();
newRow["CustomerID"] = 55;
dataSet.Tables["Customers"].Rows.Add(newRow);
new SqlCommandBuilder(dataAdapter);
dataAdapter.Update(dataSet);
You can fill the dataSet with an empty set e.g.:
da = new SqlDataAdapter ("SELECT * FROM Customers WHERE id = -1", conn);
dataSet = new DataSet();
da.Fill(dataSet);
Then you add your rows and call update.
For this scenario though it would probably be better not to use SqlDataAdapter. Instead use the SqlCommand object directly for insertion. (Even better, use LINQ to SQL or any other ORM)
SqlConnection con = new SqlConnection("Data Source=(local);Initial Catalog=test;Integrated Security=True");
SqlDataAdapter da=new SqlDataAdapter("Insert Into Employee values("+textBox1.Text+",'"+textBox2.Text+"','"+textBox3.Text+"',"+textBox4.Text+")",con);
DataSet ds = new DataSet();
da.Fill(ds);
I have to do first time. You can try it . It works well.

Categories