Unable to update database table using Asp.net MVC - c#

I'm trying to update a column in a database table based on count however it keeps returning a value of 0 and not increment. When the user clicks the approve button then the line number should be updated using this method This is what I have so far.
public void SetRequisitionStatus0(List <string> reqNumbers, List <string> item_no)
{
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand();
command.CommandText = "requisition_sp_setstatus0";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#reqNumber", SqlDbType.VarChar);
command.Parameters.Add("#item_no", SqlDbType.VarChar);
//command.Parameters.Add("#ApprovedBy", SqlDbType.VarChar);
command.Parameters.Add("#approve_date", SqlDbType.DateTime).Value = DateTime.Now;
command.Parameters.Add("#line_num", SqlDbType.Int);
using (command.Connection = connection)
{
try
{
connection.Open();
for (int i = 0; i < reqNumbers.Count; i++)
{
command.Parameters["#reqNumber"].Value = reqNumbers[i];
command.Parameters["#item_no"].Value = item_no[i];
command.Parameters["#line_num"].Value = i;
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
connection.Close();
}
}
return;
}

Related

Function that is supposed to insert a list of objects into a database only inserts one of the objects n times

I've been trying to create a function that will set up an order for all the items that are lacking in my inventory.
RequiredStockForAllOrders basically assigns a value to each object in stockItems which lets me know how many items I need to order.
I checked with a messagebox which does the change in values (both ID and quantity) but when I run the loop that is supposed to insert each product with its respective quantity I only insert 1 product n times where n is the amount of items in the list.
private void AddAllRequiredItems_Click(object sender, EventArgs e)
{
var stockItems = new List<MyData>();
//MyData is an object with a productID int and a productQuantity int
RequiredStockForAllOrders(stockItems);
//determining the quantity required for each item
OleDbConnection con = new OleDbConnection(DatabaseConnectionString);
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
con.Open();
string sql2 = "INSERT INTO restockingDetails(RestockingID,ProductID,Quantity,Shop_ID) values (#restockingID,#productID,#quantity,#shop_id)";
cmd.CommandText = sql2;
int i = 0;
while (i < stockItems.Count)
{
try
{
MessageBox.Show(stockItems[i].productId.ToString()); //For testing
cmd.Parameters.AddWithValue("#restockingID", restockingOrder);
cmd.Parameters.AddWithValue("#productID", stockItems[i].productId);
cmd.Parameters.AddWithValue("#quantity", stockItems[i].productQuantity);
cmd.Parameters.AddWithValue("#shop_id", shopIDGlobal);
cmd.ExecuteNonQuery();
MessageBox.Show(" Item added to list"); //for testing
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
i = i + 1;
}
con.Close()
}
Just add this line before adding the parameters
MessageBox.Show(stockItems[i].productId.ToString()); //For testing
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#restockingID", restockingOrder);
You actual code continues to add parameters to the command collection, but the query uses only the first four. With other providers this code will result in an error (too many parameters) but OleDb is somebit limited in this point. Probably because it doesn't recognize parameters by their name, but by their position
A better approach could be to define the parameters just once and then updating their values inside the loop
private void AddAllRequiredItems_Click(object sender, EventArgs e)
{
var stockItems = new List<MyData>();
RequiredStockForAllOrders(stockItems);
string sql2 = "INSERT INTO restockingDetails(RestockingID,ProductID,Quantity,Shop_ID) values (#restockingID,#productID,#quantity,#shop_id)";
using(OleDbConnection con = new OleDbConnection(DatabaseConnectionString))
using(OleDbCommand cmd = new OleDbCommand(sql2, con))
{
con.Open();
cmd.Parameters.Add("#restockingID", OleDbType.Integer);
cmd.Parameters.Add("#productID", OleDbType.Integer);
cmd.Parameters.Add("#quantity", OleDbType.Integer);
cmd.Parameters.Add("#shop_id", OleDbType.Integer);
foreach(MyData item in stockItems)
{
try
{
cmd.Parameters["#restockingID"].Value = restockingOrder;
cmd.Parameters["#productID"].Value = item.productId;
cmd.Parameters["#quantity"].Value = item.productQuantity;
cmd.Parameters["#shop_id"].Value = shopIDGlobal;
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
create the command into the while loop :
OleDbConnection con = new OleDbConnection(DatabaseConnectionString);
OleDbCommand cmd;
string sql2 = "INSERT INTO restockingDetails(RestockingID,ProductID,Quantity,Shop_ID) values (#restockingID,#productID,#quantity,#shop_id)";
int i = 0;
while (i < stockItems.Count)
{
try
{
MessageBox.Show(stockItems[i].productId.ToString()); //For testing
cmd = new OleDbCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = sql2;
cmd.Parameters.AddWithValue("#restockingID", restockingOrder);
cmd.Parameters.AddWithValue("#productID", stockItems[i].productId);
cmd.Parameters.AddWithValue("#quantity", stockItems[i].productQuantity);
cmd.Parameters.AddWithValue("#shop_id", shopIDGlobal);
cmd.ExecuteNonQuery();
MessageBox.Show(" Item added to list"); //for testing
con.Close()
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
i = i + 1;
}

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

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

ASP.NET Execute SQL Server stored procedure multiple times async

I am calling a stored procedure via ASP.NET now I am trying to call it 200 times async, I am trying to do this by adding a transaction, however its not working out, here is my code:
try
{
using (connection = new SqlConnection(connectionString))
{
connection.Open();
transaction = connection.BeginTransaction();
for (int i = 0; i < 200; i++)
{
using (SqlCommand command = new SqlCommand("TimeSlotAppointments", connection))
{
command.Transaction = transaction;
command.CommandType = CommandType.StoredProcedure;
SqlParameter parameter1 = command.Parameters.Add("#StartTime", SqlDbType.DateTime);
parameter1.Direction = ParameterDirection.Input;
parameter1.Value = DateTime.Now;
command.ExecuteNonQuery();
}
}
transaction.Commit();
}
}
catch (SqlException e)
{
Console.Write(e);
transaction.Rollback();
}
finally
{
connection.Close();
connection.Dispose();
}
I am passing the current date and time as a parameter and when I check out the results in SQL Server I am expecting the #StartTime to be the same, but they are not, close, but the milliseconds increase for each record, am I going about this the wrong way? What I am trying to accomplish is executing the store procedure 200 times simultaneously.
The start time value is different because you are assigning the value inside the loop and in every iteration, the time has changed (a few milliseconds as you mentioned). If you want to use the same value for all calls, then you need to store the time stamp outside the loop in a variable and use that value in your loop.
This is how your code should look like:
try
{
using (connection = new SqlConnection(connectionString))
{
connection.Open();
transaction = connection.BeginTransaction();
var startTime = DateTime.Now; // I added this line
for (int i = 0; i < 200; i++)
{
using (SqlCommand command = new SqlCommand("TimeSlotAppointments", connection))
{
command.Transaction = transaction;
command.CommandType = CommandType.StoredProcedure;
SqlParameter parameter1 = command.Parameters.Add("#StartTime", SqlDbType.DateTime);
parameter1.Direction = ParameterDirection.Input;
parameter1.Value = startTime; // I changed this line
command.ExecuteNonQuery();
}
}
transaction.Commit();
}
}
catch (SqlException e)
{
Console.Write(e);
transaction.Rollback();
}
finally
{
connection.Close();
connection.Dispose();
}

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

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