The data source object is invalid - c#

I got this error! When open crystal report upon follong code.
The data source object is invalid.
Code is here
Cursor = Cursors.WaitCursor;
timer1.Enabled = true;
CrystalReport2 rpt = new CrystalReport2();
obj.connection();
String accept = "SELECT S.Product as Products, COALESCE(Pur_Orders.Quantity, 0) as [Products purchased], COALESCE(Sale_Orders.Quantity, 0) as [Products Sold] From Inv_stock S LEFT JOIN (SELECT Item, SUM(Quantity) AS Quantity FROM Pur_Orders Where Pur_Orders.Date='" + dateTimePicker1.Value.Date + "' GROUP BY Item) AS Pur_Orders ON S.Product = Pur_Orders.Item LEFT JOIN (SELECT Item, SUM(Quantity) AS Quantity FROM Sale_Orders Where Sale_Orders.Date='" + dateTimePicker1.Value.Date + "' GROUP BY Item) AS Sale_Orders ON S.Product = Sale_Orders.Item";
SqlCommand cmd = new SqlCommand(accept, obj.con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds, "Inv_stock");
da.Fill(ds, "Pur_Orders");
da.Fill(ds, "Sale_Orders");
rpt.SetDataSource(da);
obj.con.Close();
Inventory inv = new Inventory();
inv.CrystalReportViewer.ReportSource = rpt;
inv.Visible = true;
What is problem?????

You are setting the datasource of the report with DataAdapter:
rpt.SetDataSource(da);
Replace it with a dataset or a datatable like this:
rpt.SetDataSource(ds); // a dataset
rpt.SetDataSource(ds.Tables["TableName"]); // a datatable

You should make a View of the Nested Query and Check it and then call that specific view when u are making a new Report as Datasourse.
If your Query is Correct but Datasourse is invalid you will not get you Desired output on the Report..

Related

Condition statements for a single row data value in a database

I am using C# to create a windows form.
I am trying to set a condition statement for a particular value that is retrieved from my database by the onclick of a button. The datatype of the column is 'integer'.
Below is my code:
string checkquantity = "SELECT `inventory_item`.`Item_Quantity_Available`FROM `inventory_item` , `patient`, `out_treatment`WHERE `inventory_item`.`Item_ID` = `out_treatment`.`Inventory_ID`AND `patient`.`Patient_ID` = `out_treatment`.`Patient_ID`AND `out_treatment`.`Patient_ID`= '" + pid + "' ";
MySqlCommand selectout = new MySqlCommand(checkquantity, connect);
MySqlDataAdapter selectdata = new MySqlDataAdapter(checkquantity, connect);
DataTable selecttable = new DataTable();
selectdata.Fill(selecttable);
DataSet ds = new DataSet();
selectdata.Fill(selecttable);
selectdata.Fill(ds);
int i = ds.Tables[0].Rows.Count;
if ( i <= 0)
{
MessageBox.Show("Out of Stock");
}
I'm new with c#.
I don't think the int i = ds.Tables[0].Rows.Count; is the right way.
Any help is much appreciated.
First of all, like #Flydog57 said, you should not concatenate your sql query. The best way is to use parameters, for example:
string checkquantity = "SELECT i.Item_Quantity_Available " +
" FROM inventory_item i JOIN out_treatment t ON i.Item_Id = t.Inventory_ID " +
" JOIN patient p ON t.Patient_ID = p.PatiendID " +
" WHERE t.Patient_ID = #Patiend_ID";
MySqlCommand selectout = new MySqlCommand(checkquantity, connect);
// set the parameter value
selectout.Parameters.AddWithValue("#Patiend_ID", patient_id_value);
MySqlDataReader rdr = cmd.ExecuteReader();
if (rdr.Read())
{
if ((int)rdr["Item_Quantity_Available"] == 0)
MessageBox.Show("Out of Stock");
}
In second place, you could use a MySqlDataReader to verify that Item_Quantity_Available is equal to 0, like in the previous example. Otherwise, If you just wants to verify if there is data, the condition could be something like that:
if (!rdr.Read())
{
MessageBox.Show("Out of Stock");
}
The third improvemente is to join tables with the join clause.

How to display Access data in a DataTable in C#?

I'm new to C#. I'm having a difficult time displaying my Access data in a DataTable. Here is the code:
try
{
reader.Read();
for (int i = 0; i < 16; i++)
{
if (selectedCourse == reader["CourseName"].ToString())
{
match = true;
}
else
{
match = false;
}
}
if (match == true)
{
tabControl.SelectedTab = tabPage1; // opens results page
string connString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\...454_Database.accdb";
DataTable results = new DataTable();
using (OleDbConnection conn = new OleDbConnection(connString))
{
OleDbCommand cmd = new OleDbCommand("Select c.PeriodID, c.CourseName, c.Teacher, t.Room"
+ "FROM Courses c JOIN Teacher t ON t.TeacherID = c.TeacherID"
+ "WHERE [CourseName] ='" + cboxClass.Text + "'", conn);
conn.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
adapter.Fill(results);
dataTblResults.DataSource = results;
I can tell the data is being compared to the db and it correctly determines if the query has results or not. However, when there are results, they do not get displayed on the data table. Is it because it doesn't know which columns correspond to the columns in the data table?
Thanks in advance!
How is your datagrid configured?
Try setting: (before setting the DataSource)
dataTblResults.AutoGenerateColumns = true;
dataTblResults.DockStyle.Fill = DockStyle.Fill;
Try using a Dataset first. Then turn it to a datatable
DataSet ds = new DataSet();
adapter.fill(ds)
if (ds.Tables[0].Rows.Count >= 1)
{
results = ds.Tables[0];
}
dataTblResults.DataSource = results;
I dont think this is what you are looking for but maybe it'll bring you closer to the answer

while updating grid view not updating all table

i am working on windows from application..i am filling my data grid view like this:
Dim cd As SqlCommandBuilder = New SqlCommandBuilder(adapter)
adapter = New SqlDataAdapter("select c.cid,c.CompanyName,l.LocName as Location,d.dtId,d.dtName as Department,d.dtPhone as Phone,d.dtEmail as Email,l.Locid from CompanyMaster_tbl c join DepartmentMaster_tbl d on c.Cid=d.cId join Location_tbl l on l.Locid=c.locid where d.Deleted =0 and c.Deleted=0 order by cid", con.connect)
dt1 = New DataTable
bSource = New BindingSource
adapter.Fill(dt1) 'Filling dt with the information from the DB
bSource.DataSource = dt1
gv.DataSource = bSource
gv.Columns("cid").Visible = False
gv.Columns("dtId").Visible = False
gv.Columns("Locid").Visible = False
in update button I have code like this:
adapter = New SqlDataAdapter()
Dim cid As Integer
Dim dtid As Integer
Dim cmpname As String
Dim dtname As String
Dim dtPhone As String
Dim dtEmail As String
Dim LocName As String
Dim Locid As Integer
For i As Integer = 0 To gv.RowCount - 2
Dim rv = DirectCast(gv.Rows(i).DataBoundItem, DataRowView)
cid = rv.Row.Field(Of Integer)("Cid")
dtid = rv.Row.Field(Of Integer)("dtId")
cmpname = rv.Row.Field(Of String)("CompanyName")
LocName = rv.Row.Field(Of String)("Location")
dtname = rv.Row.Field(Of String)("Department")
dtPhone = rv.Row.Field(Of String)("Phone")
dtEmail = rv.Row.Field(Of String)("Email")
Locid = rv.Row.Field(Of Integer)("Locid")
adapter.UpdateCommand = New SqlCommand("UPDATE CompanyMaster_tbl SET CompanyName = #CompanyName", con.connect)
adapter.UpdateCommand = New SqlCommand("Update Location_tbl Set LocName=#LocName where Locid=#Locid ", con.connect)
adapter.UpdateCommand = New SqlCommand("update DepartmentMaster_tbl set dtName = #dtName,dtPhone = #dtPhone,dtEmail = #dtEmail where dtId=#dtid", con.connect)
adapter.UpdateCommand.Parameters.AddWithValue("#Cid", cid)
adapter.UpdateCommand.Parameters.AddWithValue("#CompanyName", cmpname)
adapter.UpdateCommand.Parameters.AddWithValue("#LocName", LocName)
adapter.UpdateCommand.Parameters.AddWithValue("#dtId", dtid)
adapter.UpdateCommand.Parameters.AddWithValue("#dtName", dtname)
adapter.UpdateCommand.Parameters.AddWithValue("#dtPhone", dtPhone)
adapter.UpdateCommand.Parameters.AddWithValue("#dtEmail", dtEmail)
adapter.UpdateCommand.Parameters.AddWithValue("#Locid", Locid)
adapter.UpdateCommand.ExecuteNonQuery()
Next
while clicking update button I am not getting any error..i can able to update my DepartmentMaster_tbl..but that is not updating my Location_tbl..what is wrong with my code..
any help is very appreciable..thanks
because you are overwriting your UpdateCommands then doing ExecuteNonQuery which will use the current UpdateCommand available (the last one in this case)
to me it looks like you are overwriting the UpdateCommand twice after setting it.
you set it with UPDATE CompanyMaster_tbl then overwrite it with UPDATE Location_tbl and then overwrite it again with update DepartmentMaster_tbl,
as expected only the last one is executed.
a solution using SqlCommand instead of SqlAdapter:
using (SqlConnection DBConn = new SqlConnection("connection string")
{
DBConn.Open();
using (SqlTransaction DBTran = DBConn.BeginTransaction)
{
using (SqlCommand DBCmd = new SqlCommand("your first statement here", DBConn))
{
DBCmd.Transaction = DBTran;
// set only the parameters needed for this table
...
// execute statement
DBCmd.ExecuteNonQuery();
}
// repeat the above block for the other tables
...
// commit transaction to database
DBTran.Commit();
}
}

SqlDataReader filling column in datagridview

I have been wondering for quiet long time how can I set my SqlDataReader to fill column "pocet" in my datagridview "dtg_ksluzby". I thought that my code should look something like this:
SqlCommand novyprikaz2 = new SqlCommand("SELECT pocet FROM klisluz WHERE id='"+vyberradek+"'",spojeni); // I also have column "pocet" in table klisluz, vyberradek is string which selectrs id number
spojeni.Open();
SqlDataReader precti2 = novyprikaz2.ExecuteReader();
if (precti2.Read())
{
dtg_ksluzby.Columns["pocet"]; // this part I need to improve to fill
}
Would you please help me to improve my code?
Thanks so much in advance.
Edit for trippino:
In "klisluz" which is in the table that includes columns
(id,akce,subkey,text,pocet). I need to:
select * from klisluz where subkey = '"+vyberradek+"'
Take column pocet and fill it into dtg_ksluzby where i find the text is similar in column "text" in dtg_ksluzby
I hope my description is understandabla, sorry for my weak english.
Do not use string concatenation to build sql commands, (to avoid Sql Injection and parsing problem)
using(SqlConnection spojeni = new SqlConnection(conString))
using(SqlCommand novyprikaz2 = new SqlCommand("SELECT pocet FROM klisluz " +
"WHERE id = #id",spojeni);
{
novyprikaz2.Parameters.AddWithValue("#id", vyberradek);
spojeni.Open();
using(SqlDataAdapter da = new SqlDataAdapter(novyprikaz2))
{
DataTable dt = new DataTable();
da.Fill(dt);
dtg_ksluzby.DataSource = dt;
}
}
Use a DataAdapter to load your data from database and pass this DataAdapter instance to the DataSource of your DataGridView
Use something like this:
for (int i = 0; i < dtg_ksluzby.Rows.Count; i++)
{
var row = dtg_ksluzby.Rows[i];
using(var novyprikaz2 = new SqlCommand("SELECT pocet FROM klisluz WHERE text LIKE #t AND subkey=#s", spojeni))
{
novyprikaz2.Parameters.AddWithValue("#t", row.Cells["text"].Value.ToString());
novyprikaz2.Parameters.AddWithValue("#s", vyberradek);
spojeni.Open();
SqlDataReader precti2 = novyprikaz2.ExecuteReader();
if (precti2.Read())
{
row.Cells["pocet"].Value = precti2["pocet"];
}
}
}

How can i get size of column of database using datatable in c#

I want to get max size of any column of a table using datatable in C#. Example is that if i have a table in database named dept and its attributes are NAME and ADDRESS and i have set size of NAME as varchar(50) and Address as varchar(30).
Now i want to get 50 and 30.....
i have written this code
DataSet ds1 = new DataSet();
DataSet ds = new DataSet();
string query = Form1.query1Pass;
SqlCommand cmd = new SqlCommand(query.ToString(), con);
this.tablename1 = query.Substring(query.LastIndexOf("from")+4); ;
cmd.ExecuteNonQuery();
SqlDataAdapter adp = new SqlDataAdapter(cmd);
adp.Fill(this.ds);
string query2 = Form1.query2Pass;
cmd = new SqlCommand(query2, con);
adp = new SqlDataAdapter(cmd);
adp.Fill(this.ds1);
StringBuilder datatype2 = new StringBuilder();
this.datatype2.Append("Data Type Conflict: ");
this.datetimeCon.Append("DateTime Format Conflict: ");
DataTable table1 = this.ds.Tables[0];
DataTable table2 = this.ds1.Tables[0]; ;
DataColumnCollection col1 = table1.Columns;
DataColumnCollection col2 = table2.Columns;
foreach (DataColumn ds in col1) {
foreach (DataColumn ds2 in col2) {
if (ds.ColumnName.Equals(ds2.ColumnName)) {
if (!ds.DataType.Equals(ds2.DataType)) {
this.datatype2.Append(ds.ColumnName + "<" + ds.DataType + ">, " + ds2.ColumnName + "<" + ds2.DataType + ">,");
}
else
if (ds.MaxLength!=ds2.MaxLength) {
maxLength.Append(ds.ColumnName+"<"+ds.MaxLength+">, "+ds2.ColumnName+"<"+ds2.MaxLength+">,");
}
}
}
}
I assume that the columns are not Text columns. The MaxLength property is only set on columns with DataType=String. MSDN:
The MaxLength property is ignored for non-text columns. A
ArgumentException exception is raised if you assign MaxLength to a
non-string column.
By the way, you might want to use a LINQ approach, but that's a matter of taste:
var t1Cols = table1.Columns.Cast<DataColumn>();
var t2Cols = table2.Columns.Cast<DataColumn>();
var diffTypes =
from t1Col in t1Cols
join t2Col in t2Cols on t1Col.ColumnName equals t2Col.ColumnName
where t1Col.DataType != t2Col.DataType
select string.Format("{0}<{1}>,{2}<{3}>",
t1Col.ColumnName, t1Col.DataType, t2Col.ColumnName, t2Col.DataType);
var diffMaxLength =
from t1Col in t1Cols
join t2Col in t2Cols on t1Col.ColumnName equals t2Col.ColumnName
where t1Col.MaxLength != t2Col.MaxLength
select string.Format("{0}<{1}>,{2}<{3}>",
t1Col.ColumnName, t1Col.MaxLength, t2Col.ColumnName, t2Col.MaxLength);
Console.WriteLine("diff. Types: " + string.Join(", ", diffTypes));
Console.WriteLine("diff. max Length: " + string.Join(", ", diffMaxLength));

Categories

Resources