SqlDataAdapter filling with DataTable does not work - c#

I have this code running in form_load event:
using (SqlConnection sqlConn = new SqlConnection(strConn))
{
sqlConn.Open();
SqlDataAdapter sqlDa = new SqlDataAdapter("pp_sp_MachineAndOp", sqlConn);
DataTable sqlDt = Helper.ExecuteDataTable("pp_sp_MachineAndOp", new SqlParameter("#MachineAndOpID", 7));
sqlDa.Fill(sqlDt);
dgvMachineAndOp.AutoGenerateColumns = false;
dgvMachineAndOp.DataSource = sqlDt;
sqlDa.Dispose();
sqlConn.Close();
}
I get error 'Procedure or function 'pp_sp_MachineAndOp' expects parameter '#MachineAndOpID', which was not supplied.' at line:
sqlDa.Fill(sqlDt);
Important to say that if I open DataTable Visualizer of sqlDt at runtime I see expected results!
Here is a code behind Helper.ExecuteDataTable:
public static DataTable ExecuteDataTable(string storedProcedureName, params SqlParameter[] arrParam)
{
DataTable dt = new DataTable();
// Open the connection
using (SqlConnection sqlConn = new SqlConnection(strConn))
{
try
{
sqlConn.Open();
// Define the command
using (SqlCommand sqlCmd = new SqlCommand())
{
sqlCmd.Connection = sqlConn;
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.CommandText = storedProcedureName;
// Handle the parameters
if (arrParam != null)
{
foreach (SqlParameter param in arrParam)
{
sqlCmd.Parameters.Add(param);
}
}
// Define the data adapter and fill the dataset
using (SqlDataAdapter da = new SqlDataAdapter(sqlCmd))
{
da.Fill(dt);
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
return dt;
}
What I am missing?

Remove everything except
DataTable sqlDt = Helper.ExecuteDataTable("pp_sp_MachineAndOp", new SqlParameter("#MachineAndOpID", 7));
dgvMachineAndOp.AutoGenerateColumns = false;
dgvMachineAndOp.DataSource = sqlDt;
your Helper.ExecuteDataTable is doing everything. you don't need to replicate same this in your code.

I think your helper class is creating connection with database as your data table has data.
So, try to remove stored proc name and connection object from adaptor and then check.
SqlDataAdapter sqlDa = new SqlDataAdapter();//use this only.

you can use below function(modification required as per your need):
public IDataReader ExecuteReader(string spName, object[] parameterValues)
{
command = GetCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = spName;
if (parameterValues != null)
{
for (int i = 0; i < parameterValues.Length; i++)
{
command.Parameters.Add(parameterValues[i]);
}
}
reader = command.ExecuteReader();
if (parameterValues != null)
command.Parameters.Clear();
return reader;
}

Related

sqlcommand c# method with sql paramather

I have this method, which I have in the base class that helps me to select anything from the children classes and also to reduce code repetition. The problem is when I call it I get an error which is a NullReferenceException (and when I look it up I find that the command in the method is empty).
This is the method in question:
This way I already know how to use but the other one I don't
SqlCommand command = new SqlCommand("select * from Customers where idCustomer=#idCustomer", OpenConnection());
command.Parameters.AddWithValue("#idCustomer", Id);
SqlDataReader reader = command.ExecuteReader();
Customer Onecustomer = null;
if (reader.Read())
{
Onecustomer = ReadCustomer(reader);
}
protected DataTable ExecuteSelectQuery(String query, params SqlParameter[] sqlParameters)
{
SqlCommand command = new SqlCommand();
DataTable dataTable;
DataSet dataSet = new DataSet();
try
{
command.Connection = OpenConnection();
command.CommandText = query;
command.Parameters.AddRange(sqlParameters);
command.ExecuteNonQuery();
adapter.SelectCommand = command;
adapter.Fill(dataSet);
dataTable = dataSet.Tables[0];
}
catch (SqlException e)
{
return null;
throw new Exception("Error :" + e.Message);
}
finally
{
CloseConnection();
}
return dataTable;
}
Here how I call it
string author = "Alfred Schmidt";
int id = 1;
// ExecuteEditQuery("UPDATE Books SET Title =#param1 WHERE idBook =#param2", sqlParameters);
//SqlParameter[] sqlParameters = new SqlParameter[1]
//{
// new SqlParameter ("#param1",author),
//};
SqlParameter[] myparm = new SqlParameter[1];
myparm[0] = new SqlParameter("#Author", SqlDbType.NVarChar, 200);
myparm[0].Value = author;
String query = #"SELECT * FROM Books WHERE Author =#Author";
DataTable dt = ExecuteSelectQuery(query, myparm);
for (int i = 0; i < dt.Rows.Count; i++)
{
Console.WriteLine(dt.Rows.ToString());
}
Console.Write("");
1
Is your OpenConnection() method returns a connection object. It may couse the error, the implementation of the method is not given. Also the adpater is not defined in the code, may be it can be the cause of error too, if it is not initialized.
And i want to say few things about your code:
1) You have and unnecessary command.ExecuteNonQuery(); statement in your ExecuteSelectQuery method.
2) DataAdapter can directly fill DataTable, you dont have to use DataSet.
Here's a proper rewrite of your method.
protected DataTable ExecuteSelectQuery(String query, params SqlParameter[] sqlParameters)
{
using (SqlCommand command = new SqlCommand())
try
{
command.CommandText = query;
command.Parameters.AddRange(sqlParameters);
command.Connection = OpenConnection();
DataTable dataTable = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
adapter.Fill(dataTable);
return dataTable;
}
catch (SqlException e)
{
return null;
throw new Exception("Error :" + e.Message);
}
finally
{
CloseConnection();
}
}
Note that the SqlDataAdapter can Open() and Close() the connection by itself, if the SqlConnection is Closed when Fill is called.

Trying to pass SqlCommand in SqlDataAdapter as parameters

I've successfully built up my method to execute a select command. It is working fine. Then I change my code for SqlDataAdapter DA = new SqlDataAdapter();
I tried to pass SqlCommand as CommandType.Text in the parameters but I can not do it successfully. I get error. Is there any way if I can pass it as parameters. Please see my code.
Running code (aspx page code)
if ((!string.IsNullOrEmpty(user_login.Value)) && (!string.IsNullOrEmpty(user_pass.Value)))
{
// username & password logic
DataTable dt = new DataTable();
string strQuery = "SELECT 1 FROM TBL_USER_INFO WHERE USERNAME = #USERNAME AND PASSWORD = #PASSWORD";
SqlCommand cmd = new SqlCommand(strQuery);
cmd.Parameters.Add("#USERNAME", SqlDbType.VarChar).Value = user_login.Value.Trim();
cmd.Parameters.Add("#PASSWORD", SqlDbType.VarChar).Value = user_pass.Value.Trim();
DBConnection conn_ = new DBConnection();
dt = conn_.SelectData(cmd);
if (conn_.SQL_dt.Rows.Count > 0)
{
Response.Redirect("Home.aspx", false);
}
}
Successful connection class code
public DataTable SelectData(SqlCommand command)
{
try
{
conn.Open();
SqlDataAdapter DA = new SqlDataAdapter();
command.CommandType = CommandType.Text;
command.Connection = conn;
DA.SelectCommand = command;
DA.Fill(SQL_dt);
return SQL_dt;
}
catch (Exception ex)
{
return null;
}
finally
{
conn.Close();
}
}
How can I pass CommandType.Text as parameters for SqlDataAdapter?
Error code
public DataTable SelectData(SqlCommand command)
{
try
{
conn.Open();
SqlDataAdapter DA = new SqlDataAdapter(command.CommandType.ToString(), conn);
// command.CommandType = CommandType.Text;
// command.Connection = conn;
DA.SelectCommand = command;
DA.Fill(SQL_dt);
return SQL_dt;
}
catch (Exception ex)
{
return null;
}
finally
{
conn.Close();
}
}
I am getting this error:
System.InvalidOperationException: Fill: SelectCommand.Connection property has not been initialized.
at System.Data.Common.DbDataAdapter.GetConnection3(DbDataAdapter adapter, IDbCommand command, String method)...
public DataTable SelectData(string query)
{
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection("Your Connection String here"))
{
con.Open();
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
using (SqlDataAdapter adp = new SqlDataAdapter(cmd))
{
adp.Fill(dt);
return dt;
}
}
}
}
To use:
SelectData("select * from yourTable");
Reds has the answer. Just to clean the code up a little bit...
public DataTable SelectData(string query)
{
using (var connection = new SqlConnection("myConnectionString"))
using (var command = new SqlCommand(query, connection))
using (var adapter = new SqlDataAdapter(command))
{
var dt = new DataTable();
connection.Open();
adapter.Fill(dt);
return dt;
}
}
Actually you should pass the connection object on SQLCommand.Hope it helped you
DBConnection conn_ = new DBConnection();
SqlCommand cmd = new SqlCommand(strQuery,conn_);
The error that you are getting is not related to CommandType.Text, it says you have initialised the connection property of of SelectCommand. Basically you should uncomment "command.Connection = conn;" to get rid of this error. If you still face any other issue , it is better to provide those details in the questions to provide accurate answer.

SQL Server with C# in Visual Studio

public DataTable getData(string procedureName, SqlParameter[] procedureParams)
{
SqlCommand command = new SqlCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = procedureName;
command.Connection = connection;
if (procedureParams != null)
{
for (int i = 0; i < procedureParams.Length; i++)
{
command.Parameters.Add(procedureParams[i]);
}
}
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable table = new DataTable();
adapter.Fill(table);
return table;
}
On the line
adapter.Fill(table);
I get an error:
An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
What's the problem? I'm doing c# inventory management system on Visual Studio and I'm struggling with this part of class db class
You need to make sure your connection is open before you can fill the datatable. The code can also be slightly consolidated.
public DataTable getData(string procedureName, SqlParameter[] procedureParams)
{
SqlCommand command = new SqlCommand(procedureName, connection);
command.CommandType = CommandType.StoredProcedure;
if (procedureParams != null)
{
for (int i = 0; i < procedureParams.Length; i++)
{
command.Parameters.Add(procedureParams[i]);
}
}
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable table = new DataTable();
if (connection.State != ConnectionState.Open)
connection.Open();
adapter.Fill(table);
connection.Close();
return table;
}
Also, note that you are not setting the timeout property of your command object, so it will use the default. That can be set as part of the command if needed.
command.CommandTimeout = my_timeout_variable;
I think you are doing wrong while filling DataTable, you shouldn't fill DataTable, instead you should fill DataSet. Try doing this
public DataTable getData(string procedureName, SqlParameter[] procedureParams)
{
SqlCommand command = new SqlCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = procedureName;
command.Connection = connection;
if (procedureParams != null)
{
for (int i = 0; i < procedureParams.Length; i++)
{
command.Parameters.Add(procedureParams[i]);
}
}
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet ds = new DataSet();
adapter.Fill(ds); //Fill DataSet and try accessing your table from DataSet
return ds.Tables[0];
}

How to pass stored procedure name as parameter in DAL

I have more than one function which simply fetches data from DB. The difference among the function is the stored procedure name (uspLoadStudents,uspLoadMarks). To optimize, make it as one function and passes the SP.
public DataSet LoadSubjects()
{
string SqlDBConnection = Utils.GetConnectionString();
DataSet ds = new DataSet();
SqlConnection sqlConn = new SqlConnection(SqlDBConnection);
SqlCommand sqlCmd = new SqlCommand("uspLoadSubjects", sqlConn);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlConn.Open();
DataTable dt = new DataTable();
dt.Load(sqlCmd.ExecuteReader());
ds.Tables.Add(dt);
sqlConn.Close();
return ds;
}
Information like sql command, stored procedure name, should be part of your Data Access Layer, instead it is a helper class inside the data access layer. Try this:
public static class DALHelper
{
public static DataSet ExecuteProcedure(string procedureName)
{
string sqlDBConnection = Utils.GetConnectionString();
DataSet ds = new DataSet();
using (SqlConnection sqlConn = new SqlConnection(sqlDBConnection))
{
using(SqlCommand sqlCmd = new SqlCommand(procedureName, sqlConn))
{
sqlCmd.CommandType = CommandType.StoredProcedure;
try
{
sqlConn.Open();
using (var adapter = new SqlDataAdpter(sqlCmd))
{
adapter.Fill(ds);
}
}
catch
{
throw;
}
finally
{
sqlConn.Close();
}
}
}
return ds;
}
}
Implement a method to use this helper, for sample:
public DataSet LoadSubjects()
{
return DALHelper.ExecuteProcedure("uspLoadStudents");
}
This?
public DataSet ExecProc(string procName)
{
string SqlDBConnection = Utils.GetConnectionString();
DataSet ds = new DataSet();
SqlConnection sqlConn = new SqlConnection(SqlDBConnection);
SqlCommand sqlCmd = new SqlCommand(procName, sqlConn);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlConn.Open();
DataTable dt = new DataTable();
dt.Load(sqlCmd.ExecuteReader());
ds.Tables.Add(dt);
sqlConn.Close();
return ds;
}
try this
public static DataSet getDataSet(string sp_name, string[] param_names, object[] param_values)
{
SqlDataAdapter sqlda = new SqlDataAdapter();
SqlCommand sqlcmd = new SqlCommand();
DataSet set = new DataSet();
try
{
sqlcmd.Connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
sqlcmd.CommandType = CommandType.StoredProcedure;
sqlcmd.CommandText = sp_name;
sqlda.SelectCommand = sqlcmd;
sqlda.Fill(set);
}
catch (Exception ex)
{
}
finally
{
if (sqlcmd.Connection.State == ConnectionState.Open)
sqlcmd.Connection.Close();
}
return set;
}

eExecuteDataSet for system.data.common.dbCommand?

I am using system.data.common.dbcommand for database communications but I couldn't find ExecuteDataSet in it. Probably it is not supported. Please advice is there some way that I can read multiple datatable in one go (my stored procedure will return multiple selects).
Thanks
Loading data into a data-set is really the job of a data-adapter, so spin up an appropriate data-adapter and use that to load the data. You can also use dataSet.Load(reader).
However, please consider: are data-sets really the best metaphor for what you are doing?
public DataSet ExecuteDataSet(string procName,
params IDataParameter[] procParams)
{
SqlCommand cmd;
return ExecuteDataSet(out cmd, procName, procParams);
}
public DataSet ExecuteDataSet(out SqlCommand cmd, string procName,
params IDataParameter[] procParams)
{
SqlConnection cnx = null;
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter();
cmd = null;
try
{
//Setup command object
cmd = new SqlCommand(procName);
cmd.CommandType = CommandType.StoredProcedure;
if (procParams != null)
{
for (int index = 0; index < procParams.Length; index++)
{
cmd.Parameters.Add(procParams[index]);
}
}
da.SelectCommand = (SqlCommand)cmd;
System.Diagnostics.Trace.Write(da.SelectCommand);
//Determine the transaction owner and process accordingly
if (_isOwner)
{
cnx = new SqlConnection(GetConnectionString());
cmd.Connection = cnx;
cnx.Open();
}
else
{
cmd.Connection = _txn.Connection;
cmd.Transaction = _txn;
}
//Fill the dataset
da.Fill(ds);
}
catch
{
throw;
}
finally
{
if (da != null) da.Dispose();
if (cmd != null) cmd.Dispose();
if (_isOwner)
{
cnx.Dispose(); //Implicitly calls cnx.Close()
}`enter code here`
}
return ds;
}

Categories

Resources