The DataSet result is always empty in C# - c#

I am retrieving particular column value using DataSet.
This is my code:
public DataSet GetRedirectURL(string emailId)
{
DataSet ds = new DataSet();
using (SqlConnection con = new SqlConnection(#"Connection_String_Here"))
{
con.Open();
SqlCommand sqlComm = new SqlCommand("usp_Login", con)
{
CommandType = CommandType.StoredProcedure
};
sqlComm.Parameters.AddWithValue("#EmailId", emailId);
SqlDataAdapter da = new SqlDataAdapter
{
SelectCommand = sqlComm
};
da.Fill(ds);
}
return ds;
}
I have also used DataTable instead of it but the same result.
I have checked my Stored Procedure and when I pass Parameter it shows Data. So, nothing wrong with the SP. But the Table doesn't show any data and is always empty as shown below:
What am I missing? Any help would be appreciated.

I'd suggest you to first evaluate the content of your DataSet. For instance, type in your Immediate Window (or add a quick watch) to check ds.Tables[0].Rows.Count. Basically, to assert your DataSet has been properly filled with the contents fetched from the database, and focus on the data assignment from the DataSet to the grid object you're using to display it.
Also, the .Fill() method has a returning object which is an int representing the amount of rows that have been successfully filled into the target object. For instance:
int result = da.Fill(ds);
Check the value of result after the .Fill() method has been executed.
Finally, I guess you're using a DataGridView object to visualize the results. If so, how are you binding data? Should be something like:
dataGridView1.DataSource = ds.Tables[0];
PS: As I've read in other comments, no, you don't need to execute the .Open() method on the connection. That's not necesarry, it's done implicitely when using the (using SqlConnection conn = SqlConnection..)

Related

Filling dataset with dataadapter with row limit

I need to modify the following code so that the number of rows are limited.
// create the connection
OracleConnection conn = new OracleConnection("Data Source=oracledb;
User Id=UserID;Password=Password;");
// create the command for the stored procedure
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT_JOB_HISTORY.GetJobHistoryByEmployeeId";
cmd.CommandType = CommandType.StoredProcedure;
// add the parameters for the stored procedure including the REF CURSOR
// to retrieve the result set
cmd.Parameters.Add("p_employee_id", OracleType.Number).Value = 101;
cmd.Parameters.Add("cur_JobHistory", OracleType.Cursor).Direction =
ParameterDirection.Output;
// createt the DataAdapter from the command and use it to fill the
// DataSet
OracleDataAdapter da = new OracleDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);//Here is where I need to limit the rows
I know there is fill method which takes a maximum count.
public int Fill(
DataSet dataSet,
int startRecord,
int maxRecords,
string srcTable
)
However, I don't know what should be passed to srcTable. My stored proc has one REF_CURSOR
(OUT TYPES.REF_CURSOR).
Any help is much appreciated.
The srcTable parameter is the name of the DataTable in DataSet object.
EDIT:
The DataSet object automatically adds a table when you call Fill if you have not explicitly created one. The Default name is "Table". I do not believe the DataSet object cares about what type of data it is being filled with. It still creates the DataTable.
Before you call Fill() on your DataAdapter. Add an empty table to the DataSet with a name so you are able to access it during the Fill() method:
ds.Tables.Add("myTableName");
Then call the proper overloaded Fill() method like so:
da.Fill(ds, 1, 1000, "myTableName");
Or if you just use the default name of the table, or are unsure of the name of the table you created (doubtful):
da.Fill(ds, 1, 1000, ds.Tables[0].TableName);
Spcifically using your example it should look like this:
OracleDataAdapter da = new OracleDataAdapter(cmd);
DataSet ds = new DataSet();
ds.Tables.Add();
da.Fill(ds, 1, maxRowCount, ds.Tables[0].TableName);//Here is where I need to limit the rows

DataSet call insert, update and delete stored procedures

Through designer I have created a typed data set and included stored procedures for insert / update / delete. The problem is now, how to call those stored procedures? How to actually change data in database this way? And how to receive answer from db (number of rows changed)?
try this for get data from database.
DataSet ds = new DataSet("dstblName");
using(SqlConnection conn = new SqlConnection("ConnectionString"))
{
SqlCommand sqlComm = new SqlCommand("spselect", conn);
sqlComm.Parameters.AddWithValue("#parameter1", parameter1value);
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = sqlComm;
da.Fill(ds);
}
Similarly you need to call "spdelte" etc.
I found out that far easiest way is through designer - create table adapter and simply set it to call stored procedure. No extra typing needed, arguments are also added to procedure call.

DataAdapter: Update unable to find TableMapping['Table'] or DataTable 'Table'

This code snippet is throwing an error:
Update unable to find TableMapping['Table'] or DataTable 'Table'.) on adapter.Update(ds); line
Why it is throwing this type of error?
SqlConnection con = new SqlConnection();
con.ConnectionString = connectionString();
DataSet ds = new DataSet();
string strQuery = "SELECT * FROM Cars";
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(strQuery, con);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.Fill(ds, "Cars");
//Code to modify data in the DataSet
ds.Tables["Cars"].Rows[0]["Brand"] = "NewBrand";
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.Update(ds);
Use
adapter.Update(ds, "Cars");
instead.
I have tested it. I got the same error without and it works if i specify the tablename. However, i must admit that i yet don't know why the DataAdapter needs to know the table-name since it has all informations it needs. If i useds.GetChanges i get one row with the correct table-name.
Update I have found nothing on MSDN but finally found it in the source(ILSpy). Here is the implementation of DBDataAdapter.Update(DataSet):
public override int Update(DataSet dataSet)
{
return this.Update(dataSet, "Table");
}
So if you don't specify a table, the table-name "Table" is used and if you've specified a table-name other than that you'll get this error, that's really strange!
I assume that the reason for this is that the DataAdapter cannot call GetChanges to determine the table to update for two reasons:
It would be inefficient since it needs to loop all tables and all of their rows to find rows with a RowState != Unchanged
It's possible that multiple tables needs to be updated since they contain changed rows. That is not supported via DataAdapter. Hence DataAdapter.Update(DataSet) assumes the default name "Table" as table-name.
Edit: However, maybe someone can explain me why the DataAdapter doesn't use DataSet.Tables[0].TableName instead.
So in general it seems to be best practise to specify the name of the table you want to update.
It's because .NET cannot assume that the table name in the DataSet/DataTable is identical to the database table. Thus .NET warns you about it.
To solve it you need to add a mapping to the DataAdapter:
da.TableMappings.Add("TableNameInDb", "TableNameInTheDataSet");
However, even if you have specified a name in the DataSet or the DataSource it still doesn't work, since the adapter seems to forget the name.
I only got it working by using:
da.TableMappings.Add("Table", "TableNameInDb");
I agree with jgauffin and I will only explain it with more text.
First, I must explain how TableMapping works. If we don't specify TableMappings with SqlDataAdapter (SqlDataAdapter that will fill our DataSet) then by default the first table will be named "Table", the second will be named "Table1", the third will be named "Table2" etc.
So, when we want to name DataTable in DataSet, we use it like this:
System.Data.DataSet myDataSet = new System.Data.DataSet();
using (System.Data.SqlClient.SqlDataAdapter dbAdapter = new System.Data.SqlClient.SqlDataAdapter(dbCommand))
{
dbAdapter.TableMappings.Add("Table", "Cars");
dbAdapter.TableMappings.Add("Table1", "Trucks");
//...
dbAdapter.Fill(myDataSet);
}
And only then we can modify it like this:
myDataSet.Tables["Cars"].Rows[0]["Brand"] = "Toyota";
myDataSet.Tables["Trucks"].Rows[0]["Brand"] = "MAN";

Combobox add rows dynamically and dropdown from SQL Server stored procedure

This is basically a search tool. When I type some thing in a combobox, the combobox drops down and will show me suggestions (something like Google search bar)
I created a procedure which does some complex calculations, which take one parameter and returns some rows. Then I created a combobox event (On Update Text).
And in the event handler I wrote this code:
private void combobox_TextUpdate(object sender, EventArgs e)
{
this.combobox.Items.Clear();
DataTable List = new DataTable();
if (this.combobox.Text.Length > 0)
{
List = searchIt(combobox.text);
foreach (DataRow Row in List.Rows)
{
this.combobox.Items.Add(Row.ItemArray.GetValue(0).ToString());
}
this.combobox.DroppedDown = true;
}
}
static public DataTable searchIt(string STR)
{
string connectionString = McFarlaneIndustriesPOSnamespace.Properties.Settings.Default.McFarlane_IndustriesConnectionString;
SqlConnection con = new SqlConnection(connectionString);
DataTable DT = new DataTable();
con.Open();
SqlDataAdapter DA = new SqlDataAdapter("USE [McFarlane Industries] " +
"EXEC search " +
STR, connectionString);
DA.Fill(DT);
con.Close();
return DT;
}
The function searchIt executes the stored procedure and it returns a DataTable. The stored procedure is working fine in SQL Server Management Studio.
But in the application it is not working correctly in some cases.
When I type [space], then it throws an exception and it says stored procedure needs parameter which is not provided.
There are many other characters when I type them it throws exception that invalid character at end of string "my string".
Any suggestion how could I achieve my goal.
Call your stored procedure with sqlcommand to fill your datatable
using (SqlConnection scn = new SqlConnection(connect)
{
SqlCommand spcmd = new SqlCommand("search", scn);
spcmd.Parameters.Add("#blah", SqlDbType.VarChar, -1); //or SqlDbType.NVarChar
spcmd.CommandType = System.Data.CommandType.StoredProcedure;
using (SqlDataAdapter da = new SqlDataAdapter(spcmd))
{
da.Fill(dt);
}
}
static public DataTable searchIt(string STR)
{
string connectionString = McFarlaneIndustriesPOSnamespace.Properties.Settings.Default.McFarlane_IndustriesConnectionString;
SqlConnection con = new SqlConnection(connectionString);
DataTable DT = new DataTable();
con.Open();
SqlCommand command = new SqlCommand("Name_of_Your_Stored_Procedure",con);
command.CommandType=CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#parameter_name",SqlDbType.NVarChar));
command.Parameters[0].Value="Your Value in this case STR";
SqlDataAdapter DA = new SqlDataAdapter(command);
DA.Fill(DT);
con.Close();
return DT;
}
Important :
'parameter_Name' and 'Name_of_Your_Stored_Procedure' should be replaced by yours which you have in database. And value of parameter could be like "abc" (combox.Text)
Command and its type, its text are necessary.
Adding parameters depends upon your stored procedure. They can be 0,1 or more but once they are added their values must be given. conn(connection) can be passed to new SqlCmmand() or new SqlDataAdapter()
No need of things like 'use' and 'exec'
Following me and this link might be helpful in future for stored procedures
http://www.codeproject.com/Articles/15403/Calling-Stored-procedures-in-ADO-NET
Two optional Suggestions for you
use variable name 'list' instead of 'List' (you used) however you will not get problem with this name until you add a namespace using System.Collections.Generic; but you may need to use this namespace in future.
Use only list.Rows[0].ToString(); no need to get itemarray then get value when you are working with data in strings;

Help with DataAdapter - DB doesn't update?

I have a data adapter. When I check the function at runtime I see the changes, but nothing happens in the database. How do I debug this? What went wrong?
OleDbDataAdapter adapter = new OleDbDataAdapter();
string queryString = "SELECT * FROM tasks";
OleDbConnection connection = new OleDbConnection(cn.ConnectionString);
adapter.SelectCommand = new OleDbCommand(queryString, connection);
OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter);
connection.Open();
adapter.Fill(ds.Tables["Tasks"]);
adapter.Update(ds);
return ds;
Nothing is happening in the database because you're running a SELECT query. What are you expecting to happen?
Well unless you snipped a lot of code, you are not changing anything in the dataset per se.
What are you trying to achieve?
Here, you are selecting some data, filling the dataset with it, then putting back the unchanged dataset in the DB.
You should first change something in the dataset itself before calling adapter.Update(ds)
Cheers,
Florian
You are selecting data via the SelectCommand. If you want to update data, you need to run the UpdateCommand.
I assume you didn't post the full source code, as it looks as though you're not modifying the dataset. However, I just tweaked your code a bit (see my comments).
Hopefully this will help...
string queryString = "SELECT * FROM tasks";
OleDbConnection connection = new OleDbConnection(cn.ConnectionString);
connection.Open(); // open connection first
SqlCommand cmd = new SqlCommand(queryString, connection);
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd); // use the cmd above when instantiating the adapter
OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter);
adapter.Fill(ds.Tables["Tasks"]);
// Modify your dataset here.
// Don't call AcceptChanges() as this will prevent the update from working.
adapter.Update(ds);
connection.Close(); // Close connection before ending the function
return ds;
This should allow OleDbCommandBuilder to do its thing by automatically scripting the database updates.
As far as I can see you've not actually changed any of the contents of the tasks table. When you call adapter.Fill you are populated the empty dataset with the records from the database. You are then calling adapter.Update without changing any records within the dataset. The update command only performs changes when the dataset > datatable > datarows are edited and marked as dirty.
you are only specifying the select command. you also need to specify the insert command... i.e:
DataAdapter.InsertCommand = new OleDbCommand....

Categories