Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
I am trying to get data from the SQL database with stored procedure using dataset and populate that data in combobox. It gives error as cannot find table 0.

C#
SqlConnection conn = new SqlConnection();
                    conn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString;
                    SqlCommand cmd2 = new SqlCommand("GetBatch", conn);
                    cmd2.CommandType = CommandType.StoredProcedure;
                    cmd2.CommandText = "usp_CAMR_GetBatch_Status";
                    cmd2.Connection = conn;
                    cmd2.Parameters.AddWithValue("@batch_name", comboBox1.Text.ToString().Substring(0, 12));
                    cmd2.Parameters.AddWithValue("@batch_status_flg", "");
                    cmd2.Parameters.AddWithValue("@BATCH_STATUS_DT", "");
                    cmd2.Parameters.AddWithValue("@BEGIN_SFN", "");
                    cmd2.Parameters.AddWithValue("@END_SFN", "");
                    cmd2.Parameters.AddWithValue("@TOTAL_SFN", "");
                    cmd2.Parameters.AddWithValue("@TOTAL_AMEND", "");
                    cmd2.Parameters.AddWithValue("@TOTAL_PAGES", "");
                    cmd2.Parameters.AddWithValue("@lst_mod_userid", "");
                    cmd2.Parameters.AddWithValue("@lst_mod_dt","");
                    cmd2.Parameters.AddWithValue("@ERR_CODE", 0);
                    cmd2.Parameters.AddWithValue("@ERR_MSG", 0);
                    cmd2.Parameters.AddWithValue("@TABLE_NAME", "");
                    cmd2.Parameters.AddWithValue("@batch_status_msg", "");
                    try
                    {
                        conn.Open();
                        SqlDataAdapter dapt = new SqlDataAdapter(cmd2);
                        dapt.Fill(ds5);
                            for (int z = 0; z < comboBox1.Items.Count; z++)
                            {
                                for (int a = 0; a < ds5.Tables[0].Rows.Count; a++)
                                {
                                    if (comboBox1.Items[z].ToString() == ds5.Tables[0].Rows[a][0].ToString())
                                    {
                                        comboBox1.Items.Add(comboBox1.Items[z] + " - " + ds5.Tables[0].Rows[a][1].ToString());
                                        comboBox1.Items.Remove(comboBox1.Items[z]);
                                    }
                                } 
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (lblerror.Text == "")
                        {
                            lblerror.Text = ex.Message;
                        }
                        else
                        {
                            lblerror.Text = lblerror.Text + ex.Message;
                        }
                    }
                    finally
                    {
                        conn.Close();
                        conn.Dispose();
                    }

Stored Procedure:

SQL
-- +==============================================================================================
@BATCH_NAME						VARCHAR(12)        OUTPUT,            
@BATCH_STATUS_FLG				CHAR(1)				OUTPUT,                     
@BATCH_STATUS_DT				DATETIME			OUTPUT, 
@BEGIN_SFN						VARCHAR(13)			OUTPUT, 
@END_SFN						VARCHAR(13)			OUTPUT, 
@TOTAL_SFN						INT					OUTPUT, 
@TOTAL_AMEND					INT					OUTPUT, 
@TOTAL_PAGES					INT					OUTPUT, 
@LST_MOD_USERID					VARCHAR(10)			OUTPUT, 
@LST_MOD_DT						DATETIME			OUTPUT,
@BATCH_STATUS_MSG				VARCHAR(256)        OUTPUT,
@ERR_CODE              			INT             	OUTPUT ,
@ERR_MSG               			VARCHAR(256)  		OUTPUT,
@TABLE_NAME         			VARCHAR(50)    		OUTPUT 
AS
	
SET NOCOUNT ON

SET @BATCH_NAME = UPPER(LTRIM(RTRIM(@BATCH_NAME)))  
SET	@BATCH_STATUS_FLG = ''            
SET @BEGIN_SFN	= ''
SET @END_SFN	= ''
SET @TOTAL_SFN	= 0
SET @TOTAL_AMEND = 0
SET @TOTAL_PAGES = 0
SET	@LST_MOD_USERID = ''
SET	@BATCH_STATUS_MSG = ''
SET @ERR_CODE   = 0
SET @ERR_MSG    = ''
SET @TABLE_NAME = 'TABLE_NAME'

SELECT @BATCH_NAME = BATCH_NAME,
@BATCH_STATUS_FLG = BATCH_STATUS_FLG,
--UPPER(RTRIM(LTRIM(BATCH_STATUS_FLG))), 
       @LST_MOD_USERID = LST_MOD_USERID,
	   @LST_MOD_DT = LST_MOD_DT
FROM DBO.CAMR_BATCH_CONTROL 
WHERE BATCH_NAME = @BATCH_NAME

SELECT   @BEGIN_SFN = ISNULL(MIN(SFN), ''), @END_SFN = ISNULL(MAX(SFN), ''),  
			@TOTAL_SFN = ISNULL(COUNT(*), 0) 
FROM  DBO.CAMR_DOCUMENT_CONTROL 
WHERE BATCH_NAME = @BATCH_NAME
AND DOC_SEQ_NUM = 1

SELECT   @TOTAL_AMEND = ISNULL(COUNT(*), 0) 
FROM  DBO.CAMR_DOCUMENT_CONTROL 
WHERE BATCH_NAME = @BATCH_NAME
AND DOC_SEQ_NUM > 1

SET @TOTAL_PAGES = @TOTAL_SFN + @TOTAL_AMEND

UPDATE DBO.CAMR_BATCH_CONTROL
SET	BEGIN_SFN 			= @BEGIN_SFN,
  	END_SFN 			= @END_SFN,
  	TOTAL_SFN			= @TOTAL_SFN,
  	TOTAL_AMEND			= @TOTAL_AMEND,
  	TOTAL_PAGES			= @TOTAL_PAGES  	
WHERE BATCH_NAME = @BATCH_NAME    

SET @ERR_CODE = @@ERROR
IF @ERR_CODE <> 0
	BEGIN
		SELECT @TABLE_NAME = 'TableName'
		SET @ERR_MSG    = CAST(@ERR_CODE AS VARCHAR(256))
		RETURN
	END

SET NOCOUNT OFF
RETURN


What I have tried:

I have tried using dataset, it works fine if I pass plain select statement to get batch name and flag statuts
Posted
Updated 12-Feb-16 10:33am
v3
Comments
Richard Deeming 12-Feb-16 15:35pm    
The stored procedure you've posted is not returning any results. If that's what you're calling, what are you expecting the DataSet to contain?
koolprasad2003 13-Feb-16 1:05am    
As Richard explained, you need to "RETURN" something to fetch it back, you re return nothing and trying to access table[0] from dataset (which is basically not exist)

1 solution

1. Always make sure your Stored Procedure returns result set from back end. i.e Database side. At least to have a SELECT Statement that returns the desired result set. And also check how to write and work with Stored Procedure[^].

2. Try to understand how ADO.NET objects such as DataSet[^], DataAdapter [^] and focus on how they work with different SQL Statements that returns result set.

3. DO NOT EVEN ATTEMPT TO USE DataSet.Tables.Count != 0 at all in your application. See the explanation below.
If you are expecting result set(s) and couldn't able to get even a single table, The above code will prevent you not to get the actual problem(exception) by further hiding it.
Technically,
1. You have a SQL Statement/Stored Procedure that returns result set(s).
2. And you used DataAdaper and DataSet to get the result set then you should at least see a single table schema inside the DataSet object.

Why is DataSet.Tables.Count != 0 is BAD in this case.
Let me take Richard Deeming[^] suggested code down in the comment.
C#
using (var connection = new SqlConnection("server=.;integrated security=SSPI;"))
using (var command = new SqlCommand("PRINT 'Hello'", connection))
{
    var ds = new DataSet();
    var da = new SqlDataAdapter(command);
    da.Fill(ds);
    
    Console.WriteLine(ds.Tables.Count);
}

This code works perfectly without issue. Happy ! Not so fast. Let see its hidden dangerous issues which leads to Logic error[^]

Issue 1. The input SQL Statement PRINT 'Hello' is not SQL Statement that can return result set(s) like SELECT SQL Statement and hence you will never ever get result set(s). This is also true for DELETE, UPDATE and other SQL Statements which are not capable of returning result set.
Issue 2. The DataAdapter object(da) was asked to fill the DataSet. i.e
C#
da.Fill(ds);
Another mistake on top of Issue 1, A DataAdapter which has a sql statement that doesn't return a result set and told to fill DataSet. This is another mistake When to use the two objects, DataAdapter and DataSet in What sql statement.
Issue 3, This is the most dangerous one. To use DataSet.Tables.Count on top of the first two issues. This eluding the entire error, the Why is not working Why I'm not getting result set, Why index of range issues by assuming you don't have table

Generally the above code always works but give unexpected result at the end, and it will be even more hard to spot the actual error.

What is the Ultimate solution then ?

1. Know the first two points suggested above. In short, Know HOW to work with Stored Procedures or SQL Statement, DataAdapter and DataSet and related objects. Know WHEN to use them in WHAT SQL Statement such as SELECT, DELETE, UPDATE etc.
2. If you are expecting result set(s) and couldn't see it in DataSet object then DO NOT ATTEMPT to hide further by using DataSet.Tables.Count == 0 or DataSet.Tables.Count != 0. See Issue 1,2,3 explanation. Face the error, figure out why it's not returning the result set, don't further hide it.
 
Share this answer
 
v5
Comments
Richard Deeming 12-Feb-16 14:46pm    
If the DataSet doesn't contain any tables, ds5.Tables[0] will throw an exception, not return null.

The condition needs to be:
if (ds5.Tables.Count != 0 && ds5.Tables[0].Rows.Count != 0)
Wonde Tadesse 12-Feb-16 15:23pm    
Not necessary. If DataSet doesn't contain any tables, dapt.Fill(ds5) will throw exception. Since it couldn't fill any tables. That's why I skip that condition. Try it before commenting.
Richard Deeming 12-Feb-16 15:26pm    
No it won't. Try it yourself before commenting! :)
Wonde Tadesse 12-Feb-16 15:30pm    
If you traverse the code as is and assuming that dapt.Fill(ds5) works properly then there is at least one table. That is what it won't throw exception.
Richard Deeming 12-Feb-16 15:33pm    
Either one or more tables are returned by the query, in which case ds5.Tables[0] will never be null; or no tables are returned by the query, in which case ds5.Tables[0] will throw an exception.

Either way, checking for ds5.Tables[0] != null is not correct.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900