In C#, I would like to run the below query on Access
query = #"SELECT Jobs.Client, Jobs.Name, Jobs.Area,
Jobs.DevHours, Sum([Activities.Duration]) AS SumOfDuration
FROM Jobs INNER JOIN Activities ON Jobs.ID = Activities.JobId
GROUP BY Jobs.Client, Jobs.Name, Jobs.Area, Jobs.DevHours;";`
After making the query, I am using a dataadapter to read and fill the data into a datatable:
OleDbCommand command = new OleDbCommand
{
CommandText = query,
Connection = connection
};
OleDbDataAdapter da = new OleDbDataAdapter(command);
DataTable table = new DataTable();
da.Fill(table);
however in run-time I face an error, which is saying
Cannot have Memo, OLE, or Hyperlink Object fields in aggregate argument ([Activities.Duration])
I really appreciate if someone can help me.
Related
I am getting error as "No values given for one or more required parameters" Please help. For Nid.Text value is "N712".
private void Form1_Load(object sender, EventArgs e)
{
OleDbConnection cont1 = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=H:\vsual\Database3.accdb");
OleDbCommand cmd1 = new OleDbCommand("select distinct UserName from Users where UID=#UID ", cont1);
OleDbCommand cmd2 = new OleDbCommand("select distinct QueueName from Users where UID=#UID ", cont1);
OleDbCommand cmd3 = new OleDbCommand("select * from Issues", cont1);
cmd1.Parameters.AddWithValue("#UID", Nid.Text);
cmd2.Parameters.AddWithValue("#UID", Nid.Text);
cont1.Open();
OleDbDataReader rdr1= cmd1.ExecuteReader();
while(rdr1.Read())
{
txtName.Text = rdr1[0].ToString();
}
OleDbDataReader rdr2 = cmd2.ExecuteReader();
while (rdr2.Read())
{
txtQueue.Text= rdr2[0].ToString();
}
txtName.Enabled = false;
txtQueue.Enabled = false;
OleDbDataAdapter da = new OleDbDataAdapter();
DataSet ds = new DataSet();
da.SelectCommand = cmd3;
da.Fill(ds);
cmbIssue.DataSource = ds.Tables[0];
cmbIssue.ValueMember = "Issues";
cmbIssue.DisplayMember = "Issues";
cmbIssue.Enabled = true;
}
All i got from internet is some issue with sql statement. Please help me out to resolve this issue.
I tried testing your code and got the same error, but then fixed up my database to match your query and it worked fine.
Upon deleting a column from the table to test, the error reappeared. So I think in this case it is just a misleading error message, and actually your database is missing a column you reference in your query (as opposed to a problem with your parameter).
e.g. deleting the QueueName column from Users broke cmd2 with the message you stated.
Have a look at your database and make sure the columns match your query. i.e. your UserName table should have columns UID, UserName, QueueName and your Issues table should have a Issues column.
Update: Adding images of the data I used to successfully run your code. Please have a look and see if anything doesn't match your data. Particularly check data types.
Users schema:
Users data:
Issues schema:
Issues data:
This might help but not sure.
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement or a stored procedure called by an OleDbCommand when CommandType is set to Text. In this case, the question mark (?) placeholder must be used. For example:
SELECT * FROM Customers WHERE CustomerID = ?
Therefore, the order in which OleDbParameter objects are added to the OleDbParameterCollection must directly correspond to the position of the question mark placeholder for the parameter in the command text.
Source : https://msdn.microsoft.com/en-us/library/system.data.oledb.oledbcommand.parameters(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
I have acquired data from my Oracle server and stored it in a DataTable (u). I have verified that the correct data has been acquired and stored.
I also have a local SQL database that has multiple tables, each with a column that carries a unique identifier.
What I would like to be able to do is compare the Oracle data stored in DataTable (u) with these various local SQL database tables, and then show the values(s) within the local SQL database tables that are identical to the values within the Oracle DataTable (u).
How would I perform this comparison while being able to tell what the matches are?
My current unfinished code:
using (OracleDataAdapter b = new OracleDataAdapter(sql2, conn))
{
conn.Open();
OracleCommand cmd2 = new OracleCommand(sql2, conn) { CommandType = CommandType.Text };
cmd2.BindByName = true;
cmd2.Parameters.Add(":user_name", OracleDbType.Varchar2).Value = cboUserName.SelectedValue;
var u = new DataTable();
b.Fill(u);
lstFunctions.DisplayMember = "Function_Name";
lstFunctions.ValueMember = "Function_Name";
lstFunctions.DataSource = u;
SqlConnection sodconnstring = new SqlConnection(#"***\SODGROUPS.sdf");
sodconnstring.Open();
SqlCommand sodcommand = new SqlCommand("SELECT * FROM tbl1, tbl2", sodconnstring);
SqlDataAdapter sodAdapter = new SqlDataAdapter(sodcommand);
var sodGroupData = new DataTable();
sodAdapter.Fill(sodGroupData);
conn.Close();
sodconnstring.Close();
}
Please let me know if you require any additional input.
Thanks.
Unless you share the schema of the tables (both oracle and SQL), it would be hard to guess a solution.
This line would return the join of tbl1 and tbl2 and I'm sure to compare the values, you would n't need a join .
SqlCommand sodcommand = new SqlCommand("SELECT * FROM tbl1, tbl2", sodconnstring)
I never used select queries with multiple tables involved before and now when I do, I'm having troubles with getting the information from the DataTable.
I have this query:
SELECT *
FROM [Usergroups], [Groups]
WHERE [Usergroups.UserID] = #name
AND [Groups.GroupID] = [Usergroups.GroupID]
And this is how I get the returned values into a DataTable:
DataTable groupsTable = new DataTable();
groupsTable.Load(sqlCmd.ExecuteReader());
Now, how can I specify my DataTable from which table I want to take rows from? For example, this is what I did before multiple tables where involved:
string groupName = groupsTable.Rows[0]["Name"];
I could not find any resource with such information, but I know it's a basic question. Thanks in advance.
The query in your question doesn't produce, as a result, multiple tables.
It produces a JOIN between two tables.
As a consequence, on the C# side, you don't have two tables but just one as before, with the all fields from both tables.
As a side note, a better way to JOIN tables together is through the use of the JOIN statement like this
SELECT * -- a field list is better here ---
FROM Usergroups ug INNER JOIN Groups g ON g.GroupID=ug.GroupID
WHERE ug.UserID=#name
and you should add, to the SELECT clause, a list of the fields that you are really interested in.
SEE a simple JOIN reference
If you want to retrieve the values of the two tables in separate DataTable objects, then you need to use a DataSet in this way
DataSet ds = new DataSet();
DataTable dtUserGroups = new DataTable("UserGroups");
DataTable dtGroups = new DataTable("Groups");
ds.Tables.Add(dtUserGroups );
ds.Tables.Add(dtGroups);
using(SqlCommand cmd = new SqlCommand("SELECT * FROM UserGroups;SELECT * from Groups", con))
{
using(SqlDataReader dr = cmd.ExecuteReader())
{
ds.Load(dr, LoadOption.OverwriteChanges, dtUserGroups, dtGroups);
// Now you have the two tables filled and
// you can read from them in the usual way
}
}
This last example could further enhanced adding a DataRelation object to the DataSet to represent the relationship between the two tables. This could allow your code to navigate the parent/child recordset.
You may try in this way :
string query = "SELECT U.ID,U.NAME, C.NAME AS CUSTOMERNAME, C.DOB FROM USER U INNER JOIN CUSTOMER C ON U.ID = C.USERID"
SqlConnection conn = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataAdapter adp = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adp.Fill(dt);
Above code will return you one DataTable with data from two different tables say "User" and "Customer".
I hope now you know how to access data from a DataTable.
It is better to use JOIN for combining multiple tables such as INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL JOIN as per your requirements. So, when you use INNER JOIN, it will have the columns of two joined tables, i.e., if
tblA has a, b,c as columns and
tblB has a, e,f as columns
then the inner joined table will have a, b, c, e, f as its columns.
Then, you can use like this:
public DataTable LoadData()
{
DataTable dataTable;
string connString = #"your connection string here";
string query = "SELECT * FROM Usergroups t1 INNER JOIN Groups t2 ON t2.GroupID=t1.GroupID WHERE t1.UserID=#name";
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();
return dataTable;
}
After Getting the DataTable, then you can use this table like:
DataTable dt = LoadDataClass.LoadData();
string groupName = dt.Rows[0]["Name"]; //For first row
I hope you get it.
in wpf c#, this method can also be used to retrieve data from multiple tables
try
{
using (SqlConnection conn = new SqlConnection(_pageDataBase.connectionString()))
{
conn.Open();
DataTable dt = new DataTable();
SqlDataAdapter Usergroups= new SqlDataAdapter("select *from Usergroups", conn);
Usergroups.Fill(dt);
SqlDataAdapter Groups= new SqlDataAdapter("select *from Groups", conn);
Groups.Fill(dt);
datagridName.ItemsSource = dt.DefaultView;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
I read SQL Command Builder class from
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommandbuilder.aspx and I found that I can show update done on dataset/database using select and update command.
SQL Command Builder concept is clear if I am using single dataset but what if I want to use two different dataset?
Scenario: I am reading values from database into one dataset ds1; which is assign to sql adapter and sql command builder. Now, I am reading only selected values from ds1 and storing into second dataset ds2; which is not assign to sql data adapter and sql command builder.
I am concern if I am updating any data on ds2 whether it will update database or not. Also, how should I do it using SQL Command builder and SQL Adapter.
//primary dataset
ds = new ProductDataSet();
command = new SqlCommand(
"SELECT no, name, price, cost, dept FROM PRODUCTS", connection);
adapter = new SqlDataAdapter();
adapter.SelectCommand = command;
adapter.Fill(ds, "table");
Primary dataset is fill on form load event. User will enter item no of his choice which will be search from primary ds and saved/display onto 2nd ds (2nd ds is not connected with with any adapter or command builder right now). For eg; 2nd ds have 3 items.
Now say user update any information on 2nd ds it should automatically update database and display on grid.
//2nd ds2 update code
for (int i = 0; i < ds2.Tables[0].Rows.Count; i++)
{
string item = ds2.Tables[0].Rows[i][0].ToString();
command = new SqlCommand("UPDATE PRODUCTS SET " + _colName + " = '" + _newValue + "'" + "WHERE ITEM_NO = '" + item + "'", Class1.conn);
datagrid.DataSource = ds2.Tables[0];
}
According to your suggestion if I am adding/declaring adapter/builder in above code it doesn't work. I am getting Table Mapping error.
Use another SQLAdapter and SQLCommandBuilder. The example on that page shows how to update your database. You just need to supply the fields to be updated in the form of a query, such as:
SELECT Name, Address, Phone, Email FROM Contact
and the command builder will generate the proper SQL UPDATE statement.
SqlCommandBuilder automatically generates INSERT, UPDATE and DELETE sql statements based on the SELECT statement for a single table.
For the Transact-SQL statements to be generated using SqlCommandBuilder, there are 2 steps
Step 1. Set the "SelectCommand" property of the SqlDataAdapter object
SqlDataAdapter dataAdapter = new SqlDataAdapter();
dataAdapter.SelectCommand = new SqlCommand("SELECT_Query", con);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet, "Students");
Step 2. Create an instance of SqlCommandBuilder class and associate the
SqlDataAdapter object created above using DataAdapter property of the SqlCommandBuilder object
SqlCommandBuilder builder = new SqlCommandBuilder();
builder.DataAdapter = dataAdapter;
Step 3. Updating records of ds1
dataAdapter.Update(ds1, "Students");
For example if I run the following query:
select * from table1
select * from table2
And run it with a DB adapter (C#) I get a dataset with two tables.
How can I define the names for the result tables in SQL?
I can only do this inside the SQL. I don't have access to the c# code.
#Timothy Khouri: It can be done! EDIT: but not at the SQL level!
You can use TableMappings on the DataAdapter.
If the SelectCommand of a DataAdapter returns multiple result sets, the DataAdapter uses table mappings to fill corresponding DataTables in a DataSet. By default, the first result set will be filled to a DataTable named "Table", and the second result set will be filled to a DataTable named "Table1" etc.
SqlDataAdapter sqlDa = new SqlDataAdapter();
SqlCommand selectCmd = new SqlCommand();
selectCmd.CommandText = "spReturnMultpileResultSets";
selectCmd.CommandType = CommandType.StoredProcedure;
selectCmd.Connection = this.sqlConnection1;
sqlDa.SelectCommand = selectCmd;
// Add table mappings to the SqlDataAdapter
sqlDa.TableMappings.Add("Table", "Customers");
sqlDa.TableMappings.Add("Table1", "Orders");
// DataSet1 is a strongly typed DataSet
DataSet1 ds = new DataSet1();
this.sqlConnection1.Open();
sqlDa.Fill(ds);
this.sqlConnection1.Close();
Refs:
http://blogs.msdn.com/vsdata/archive/2007/03/08/tableadapter-multiple-result-sets.aspx
http://www.eggheadcafe.com/software/aspnet/32696845/strongly-typed-datasets.aspx