C# SQL Error The SqlParameter is already contained by another SqlParameterCollection - c#

I have developed a simple Windows application. To reuse code I have created a separate class file for database management named as DM.
All is working fine except I am getting this error which is not being solved.
The error looks similar to the link The SqlParameter is already contained by another SqlParameterCollection - Does using() {} cheat?
but the solution is not working for me.
My code:
SqlParameter[] SQL_Params =
{
new SqlParameter("#app_srno", textBox1.Text.Trim()),
new SqlParameter("#resetBy", username_Form)
};
queryString = "insert into Record_Reset (app_srno, resetBy) values(#app_srno, #resetBy)";
DM.execute_query(queryString, SQL_Params);
// sqlParams = null;
queryString = "update [KYC_Index] set [transform_int] = 'N',[transform_int_by] = null,[transform_pic] = '',[transform_poi] = '',[transform_poa] = '',[transform_by]=null,[qc_int]='N',[qc_int_by]=null,[qc]='N',[qc_by]=null where [srno] = #app_srno";
DM.execute_query(queryString, SQL_Params); // error happens here
The code in my class file DM
public void execute_query(string query, SqlParameter[] sqlparams = null)
{
using (SqlConnection connection = new SqlConnection(connectString))
{
using (SqlCommand sqlcmd = new SqlCommand(query))
{
sqlcmd.Connection = connection;
if (sqlparams == null)
{
sqlcmd.CommandType = CommandType.Text;
}
else
{
sqlcmd.CommandType = CommandType.StoredProcedure;
foreach (SqlParameter p in sqlparams)
{
sqlcmd.Parameters.Add(p);
}
}
try
{
connection.Open();
sqlcmd.ExecuteNonQuery();
sqlparams = null;
sqlcmd.Parameters.Clear();
connection.Close();
}
catch (Exception)
{
//MessageBox.Show(ex.Message);
}
}
}
}

Related

SqlDataAdapter filling with DataTable does not work

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;
}

C# SqlDataAdapter Must declare the scalar variable Sql Exception

New to C# and working on a Windows Form application. I am attempting to execute an update query against a SQL database, but keep running into "Must declare the scalar variable" error and I do not understand why.
The below code successfully opens the connection. My update statement is valid. Looking through a lot of posts on this topic and I am just not seeing my error... any help would be appreciated.
public void SetJobStatus(long JobId)
{
string strSql = "update Jobmaster set jobstatus = 5 where equid = #stationId AND ID <> #jobId AND OfflineEntry = 0;";
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = GlobalVars.connString;
conn.Open();
// use the connection here, and check to confirm it is open
if (conn.State != ConnectionState.Open)
{
if (conn != null)
{
conn.Close();
}
conn.Open();
}
SqlCommand command;
SqlDataAdapter adapter = new SqlDataAdapter();
command = new SqlCommand(strSql, conn);
//below AddWithValue gives error:
//System.Data.SqlClient.SqlException: 'Must declare the scalar variable "#stationId".'
//command.Parameters.AddWithValue("#stationId", 1);
//command.Parameters.AddWithValue("#jobId", JobId);
//next I tried this, and the same error:
//System.Data.SqlClient.SqlException: 'Must declare the scalar variable "#stationId".'
command.Parameters.Add("#stationId", SqlDbType.Int);
command.Parameters["#stationId"].Value = 1;
command.Parameters.Add("#jobId", SqlDbType.Int);
command.Parameters["#jobId"].Value = JobId;
adapter.UpdateCommand = new SqlCommand(strSql, conn);
adapter.UpdateCommand.ExecuteNonQuery();
}
}
I have checked your code and it's required some changes. Please try to run below code:
public void SetJobStatus(int JobId)
{
string strSql = "update Jobmaster set jobstatus = 5 where equid = #stationId AND ID <> #jobId AND OfflineEntry = 0;";
using (SqlConnection conn = new SqlConnection())
{
try
{
conn.ConnectionString = GlobalVars.connString;
conn.Open();
SqlCommand command = new SqlCommand(strSql, conn);
command.CommandType = CommandType.Text;
command.Parameters.Add("#stationId", SqlDbType.Int);
command.Parameters["#stationId"].Value = 1;
command.Parameters.Add("#jobId", SqlDbType.Int);
command.Parameters["#jobId"].Value = JobId;
command.ExecuteNonQuery();
}
catch (Exception ex)
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
}
finally
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
}
}
}
Tips:
Always close connection after completion of task or in case of error.
Thanks to everyone who chimed in here. WSC's comment did the trick- changing adapter.UpdateCommand = command; worked. I tried three variations of adding parameters after making WSC's change- two of them worked, one did not.
My revised code is below. I have all three variations listed in the code- hopefully this will help somebody else out.
public void SetJobStatus(long JobId)
{
string strSql = "update Jobmaster set jobstatus = 5 where equid = #stationId AND ID <> #jobId AND OfflineEntry = 0;";
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = GlobalVars.connString;
conn.Open();
// use the connection here, and check to confirm it is open
if (conn.State != ConnectionState.Open)
{
if (conn != null)
{
conn.Close();
}
conn.Open();
}
SqlCommand command;
SqlDataAdapter adapter = new SqlDataAdapter();
command = new SqlCommand(strSql, conn);
//works
command.Parameters.AddWithValue("#stationId", GlobalVars.stationId);
command.Parameters.AddWithValue("#jobId", JobId);
//works
//command.Parameters.Add("#stationId", SqlDbType.Int);
//command.Parameters["#stationId"].Value = 5;
//command.Parameters.Add("#jobId", SqlDbType.Int);
//command.Parameters["#jobId"].Value = JobId;
//throws error at adapter.UpdateCommand.ExecuteNonQuery line:
//'The parameterized query '(#stationId int,#jobId int)update Jobmaster set jobstatus = 5 wh' expects the parameter '#stationId', which was not supplied.'
//command.Parameters.Add("#stationId", SqlDbType.Int, 5);
//command.Parameters.Add("#jobId", SqlDbType.Int, (int)JobId);
adapter.UpdateCommand = command;
adapter.UpdateCommand.ExecuteNonQuery();
}
}

Retrieving data from SQL Server with a stored procedure with ASP.net and c#

I have a form and I want to retrieve data from a sql table and show it in the form's fields depending on the ?id I enter in the url, but I always get this error:
Procedure or function 'GetAppForm' expects parameter '#id', which was
not supplied.
Note: GetAppForm is the stored procedure.
Here's my code, please help me:
try
{
if (String.IsNullOrEmpty(Request.QueryString["id"]))
{
sqlConn.Open();
using (SqlCommand cmd = new SqlCommand("GetAppForm", sqlConn))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter id = cmd.Parameters.Add("#id", SqlDbType.Int);
id.Direction = ParameterDirection.Input;
id.Value = Request.QueryString["id"];
SqlDataReader dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (dataReader.Read())
{
OwnerField.Text = dataReader["Owner"].ToString();
OdBookNoField.Text = dataReader["OD"].ToString();
PdLocField.Text = dataReader["pd"].ToString();
StatementNoField.Text = dataReader["Statmnt"].ToString();
ApplicationNoField.Text = dataReader["AppNo"].ToString();
AppDateField.Text = dataReader["AppDate"].ToString();
areaField.Text = dataReader["Area"].ToString();
areaNoField.Text = dataReader["AreaNo"].ToString();
blockNoField.Text = dataReader["BlockNo"].ToString();
streetNoField.Text = dataReader["StreetNo"].ToString();
}
}
}
}
catch (Exception ex)
{
HttpContext.Current.Response.Write("No Connection!!");
}
finally
{
sqlConn.Close();
}
Change
if (String.IsNullOrEmpty(Request.QueryString["id"]))
to
if (!String.IsNullOrEmpty(Request.QueryString["id"]))
I think you just forgot to negate the String.IsNullOrEmpty condition:
try
{
if (!String.IsNullOrEmpty(Request.QueryString["id"]))
{
Please note, your code is prone to injection.
try
{
if (!String.IsNullOrEmpty(Request.QueryString["id"]))
{
sqlConn.Open();
using (SqlCommand cmd = new SqlCommand("GetAppForm", sqlConn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#id", Request.QueryString["id"]);
SqlDataReader dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
//SqlDataReader dataReader = cmd.ExecuteReader(CommandBehavior.SingleRow);
while (dataReader.Read())
{
OwnerField.Text = dataReader["Owner"].ToString();
OdBookNoField.Text = dataReader["OD"].ToString();
PdLocField.Text = dataReader["pd"].ToString();
StatementNoField.Text = dataReader["Statmnt"].ToString();
ApplicationNoField.Text = dataReader["AppNo"].ToString();
AppDateField.Text = dataReader["AppDate"].ToString();
areaField.Text = dataReader["Area"].ToString();
areaNoField.Text = dataReader["AreaNo"].ToString();
blockNoField.Text = dataReader["BlockNo"].ToString();
streetNoField.Text = dataReader["StreetNo"].ToString();
}
}
}
}
catch (Exception ex)
{
HttpContext.Current.Response.Write("No Connection!!");
}
finally
{
sqlConn.Close();
}

Unable to execute MySql stored procedure from c#

In MySql:
DELIMITER //
DROP PROCEDURE IF EXISTS `testdb`.`Check_UserId_Sproc` //
CREATE PROCEDURE `testdb`.`Check_UserId_Sproc` (IN User_Id NVARCHAR(100))
BEGIN
select count(*) from demo_user where userid = User_Id;
END //
DELIMITER ;
In C#:
public DataTable ExecuteParameterizedSelectCommand(string CommandName, CommandType cmdType,MySqlParameter[] param)
{
DataTable table = new DataTable();
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using(MySqlConnection con = new MySqlConnection(CS))
{
using (MySqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = CommandName;
cmd.Parameters.AddRange(param);
try
{
if (con.State != ConnectionState.Open)
{
con.Open();
}
using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
{
da.Fill(table);
}
}
catch
{
throw;
}
return table;
}
}
}
public DataTable checkExistingUserId()
{
MySqlDBHelper oHelper = new MySqlDBHelper();
MySqlParameter[] parameters = new MySqlParameter[]
{
new MySqlParameter("User_Id", 'DemoId')
};
return oHelper.ExecuteParameterizedSelectCommand("Check_UserId_Sproc", CommandType.StoredProcedure, parameters);
}
When I try to execute the checkExistingUserId(), I get following exception:
Incorrect number of arguments for PROCEDURE testdb.Check_UserId_Sproc; expected 1, got 0
May be I am doing a silly mistake but I am not able to figure it out. I am new to mysql and trying to work around it.
When I debug the array contains the parameter as seen in below image, but it is not collected by the SP.
Thanks in advance
In your code:
cmd.CommandType = CommandType.Text;
should be
cmd.CommandType = cmdType;

Transactions in C#

In addition to this question: Preorder tree traversal copy folder
I was wondering if it is possible to create a transaction that contains different calls to the database.
ex:
public bool CopyNode(int nodeId, int parentNode)
{
// Begin transaction.
try
{
Method1(nodeId);
Method2(nodeId, parentNode);
Method3(nodeId);
}
catch (System.Exception ex)
{
//rollback all the methods
}
}
I don't know if this is possible. We are using subsonic to do the database calls.
This is really important, not only for the tree traversal problem but also for some other stuff we do.
The main idea is that we can't let our dabase get corrupted with uncomplete data.
That is possible, you can find a example here
Or perhaps a transaction scope...
http://msdn.microsoft.com/en-us/library/ms172152.aspx
BeginTransaction is called off a ADO.NET collection object.
The Command object needs this transaction (SqlTransaction object) assigned to it.
Commit and Rollback are only called in the outer method.
Check out this code. It works by re-using the SqlConnection and SqlTransaction objects. This is a classic Master>Details type of set up. The master type is ColumnHeaderSet which contains a property of
List<ColumnHeader>
, which is the details (collection).
Hope this helps.
-JM
public static int SaveColumnHeaderSet(ColumnHeaderSet set)
//save a ColumnHeaderSet
{
string sp = ColumnSP.usp_ColumnSet_C.ToString(); //name of sp we're using
SqlCommand cmd = null;
SqlTransaction trans = null;
SqlConnection conn = null;
try
{
conn = SavedRptDAL.GetSavedRptConn(); //get conn for the app's connString
cmd = new SqlCommand(sp, conn);
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
trans = conn.BeginTransaction();
cmd.Transaction = trans; // Includes this cmd as part of the trans
//parameters
cmd.Parameters.AddWithValue("#ColSetName", set.ColSetName);
cmd.Parameters.AddWithValue("#DefaultSet", 0);
cmd.Parameters.AddWithValue("#ID_Author", set.Author.UserID);
cmd.Parameters.AddWithValue("#IsAnonymous", set.IsAnonymous);
cmd.Parameters.AddWithValue("#ClientNum", set.Author.ClientNum);
cmd.Parameters.AddWithValue("#ShareLevel", set.ShareLevel);
cmd.Parameters.AddWithValue("#ID_Type", set.Type);
//add output parameter - to return new record identity
SqlParameter prm = new SqlParameter();
prm.ParameterName = "#ID_ColSet";
prm.SqlDbType = SqlDbType.Int;
prm.Direction = ParameterDirection.Output;
cmd.Parameters.Add(prm);
cmd.ExecuteNonQuery();
int i = Int32.Parse(cmd.Parameters["#ID_ColSet"].Value.ToString());
if (i == 0) throw new Exception("Failed to save ColumnHeaderSet");
set.ColSetID = i; //update the object
//save the ColumnHeaderList (SetDetail)
if (ColumnHeader_Data.SaveColumnHeaderList(set, conn, trans)==false) throw new Exception("Failed to save ColumnHeaderList");
trans.Commit();
// return ID for new ColHdrSet
return i;
}
catch (Exception e){
trans.Rollback();
throw e;
}
finally{
conn.Close();
}
}
public static bool SaveColumnHeaderList(ColumnHeaderSet set, SqlConnection conn, SqlTransaction trans)
//save a (custom)ColHeaderList for a Named ColumnHeaderSet
{
// we're going to accept a SqlTransaction to maintain transactional integrity
string sp = ColumnSP.usp_ColumnList_C.ToString(); //name of sp we're using
SqlCommand cmd = null;
try
{
cmd = new SqlCommand(sp, conn); // re-using the same conection object
cmd.CommandType = CommandType.StoredProcedure;
cmd.Transaction = trans; // includes the cmd in the transaction
//build params collection (input)
cmd.Parameters.Add("#ID_ColSet", SqlDbType.Int);
cmd.Parameters.Add("#ID_ColHeader", SqlDbType.Int);
cmd.Parameters.Add("#Selected", SqlDbType.Bit);
cmd.Parameters.Add("#Position", SqlDbType.Int);
//add output parameter - to return new record identity
//FYI - #return_value = #ID_SavedRpt
SqlParameter prm = new SqlParameter();
prm.ParameterName = "#ID";
prm.SqlDbType = SqlDbType.Int;
prm.Direction = ParameterDirection.Output;
cmd.Parameters.Add(prm);
//Loop
foreach (ColumnHeader item in set.ColHeaderList)
{
//set param values
cmd.Parameters["#ID_ColSet"].Value = set.ColSetID;
cmd.Parameters["#ID_ColHeader"].Value = item.ColHeaderID;
cmd.Parameters["#Selected"].Value = item.Selected;
cmd.Parameters["#Position"].Value = item.Position;
cmd.ExecuteNonQuery();
int i = Int32.Parse(cmd.Parameters["#ID"].Value.ToString());
if (i == 0) throw new Exception("Failed to save ColumnHeaderSet");
}
return true;
}
catch (Exception e)
{
throw e;
}
}

Categories

Resources