Passing Parameter to a TextBox - c#

I am am trying to pass a parameter into my textbox which communicates to my database and runs a stored procedure on a button click.
I have the button working if I hard code a parameter value but I need to to accept parameters in a textbox.
Any ideas how I can fix this code to accomplish this?
This is one of my classes
public FixPayrollMonth PayrollMonth()
{
return StoreProcPayrollMonth("fix_Payroll_PayingMonth");
}
private FixPayrollMonth StoreProcPayrollMonth(string storeprocedurename)
{
FixPayrollMonth result = new FixPayrollMonth() {IsSuccess = false };
SqlCommand cmd = new SqlCommand(storeprocedurename, Connection);
cmd.Parameters.Add(new SqlParameter("#Month_Change", 123456 ));
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Connection.Open();
using (var data = cmd.ExecuteReader())
{
while (data.Read())
{
result.MonthChanged = Convert.ToInt32(data["MonthChanged"]);
result.IsSuccess = Convert.ToBoolean(data["IsSuccess"]);
}
}
return result;
}
This is my button click...I need to link it to my textbox called txtPay
protected void btnFixMnth_Click(object sender, EventArgs e)
{
var result = repo.PayrollMonth();
if (result.IsSuccess)
{
lblMessageBoxMnthChg.Text = "Succesful Month has been changed to: " + result.MonthChanged;
}
else
{
lblMessageBoxMnthChg.Text = "Failed to change month";
}
}

Your call to repo.PayrollMonth would required a parameter to pass in the value of the textbox. So in your button click event you would do:
var result = repo.PayrollMonth(txtPay.Text);
And you repo would need to be modified to look like the following:
public FixPayrollMonth(string pay)
{
StoreProcPayrollMonth("fix_Payroll_PayingMonth", pay);
}
private FixPayrollMonth StoreProcPayrollMonth(string storeprocedurename, string pay)
{
FixPayrollMonth result = new FixPayrollMonth() {IsSuccess = false };
SqlCommand cmd = new SqlCommand(storeprocedurename, Connection);
cmd.Parameters.Add(new SqlParameter("#Month_Change", pay ));
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Connection.Open();
using (var data = cmd.ExecuteReader())
{
while (data.Read())
{
result.MonthChanged = Convert.ToInt32(data["MonthChanged"]);
result.IsSuccess = Convert.ToBoolean(data["IsSuccess"]);
}
}
return result;
}

Related

ExecuteReader query with inside of it two ExecuteNonQuery

I've got a problem with some queries from c# to SQL. I need to have a query executeReader and inside of it a if else that allow me to choose between two inserts queries. I'm calling a little external program(with the URL collected into the db) which allows me to choose between 1 and 2, if the 1 is chosen(pass) else(fail). I can't do that because the debug is giving me:
'A Command is yet associated with a DataReader opened, which needs to be closed.'
I don't know what to try anymore.
private void btnSTART_Click(object sender, RoutedEventArgs e)
{
sqliteCon.Open();
if (sqliteCon.State == System.Data.ConnectionState.Open)
{
string path = null;//estrazione1
SqlCommand cmd = new SqlCommand("select nomeI FROM tabL where selection=1", sqliteCon);
SqlDataReader nomeIRdr = null;//estrazione2
//qui
var scriptsToRun = new List<string>();
using (nomeIRdr = cmd.ExecuteReader())
{
while (nomeIRdr.Read())//estrazione4
{
path = nomeIRdr["nomeI"].ToString();//estrazione5
Process MyProc = Process.Start(path);//permette la run del path contenuto nel db
MyProc.WaitForExit();
var exitCode = MyProc.ExitCode;
if (exitCode == 1)
{
scriptsToRun.Add("insert into tabL resItem values 'PASS'");
}
else
{
scriptsToRun.Add("insert into tabL resItem values 'FAIL'");
}
sqliteCon.Close();
}
}
foreach (var script in scriptsToRun)
{
SqlCommand cmd1 = new SqlCommand(script, sqliteCon);
cmd1.ExecuteNonQuery();
}
}
}
Do not share single connection and cram everything into a single routine. Please, keep your code simple.
Create (and Dispose) Connection whenever you query RDBMS
Extract methods
Code:
Process execution and return execution results collection:
// Item1 - path
// Item2 - true in succeed
private List<Tuple<string, bool>> ExecuteResults() {
List<Tuple<string, bool>> result = new List<Tuple<string, bool>>();
using (var con = new SqlConnection(ConnectionStringHere)) {
con.Open();
string sql =
#"select nomeItem
from tabList
where selection = 1";
using (SqlCommand cmd = new SqlCommand(sql, con)) {
using (var reader = cmd.ExecuteReader()) {
while (reader.Read()) {
string path = Convert.ToString(reader[0]);
using (Process process = Process.Start(path)) {
process.WaitForExit();
result.Add(Tuple.Create(path, process.ExitCode == 1));
}
}
}
}
}
return result;
}
Saving results in RDBMS
private void ApplyExecuteResults(IEnumerable<Tuple<string, bool>> results) {
using (var con = new SqlConnection(ConnectionStringHere)) {
con.Open();
string sql =
#"update tabList
set resItem = #prm_resItem
where nomeItem = #prm_nomeItem";
using (SqlCommand cmd = new SqlCommand(sql, con)) {
cmd.Parameters.Add("#prm_nomeItem", SqlDbType.VarChar);
cmd.Parameters.Add("#prm_resItem", SqlDbType.VarChar);
foreach (var item in results) {
cmd.Parameters[0].Value = item.Item1;
cmd.Parameters[1].Value = item.Item2 ? "PASS" : "FAIL";
cmd.ExecuteNonQuery();
}
}
}
}
Finally, combine both routines:
private void btnSTART_Click(object sender, RoutedEventArgs e) {
ApplyExecuteResults(ExecuteResults());
}

SQLDataReader bugging while using .Nest() or .Read()

I'm retrieving some information from an MSSQL via SQLDataReader, but while debugging it I notice in some cases the reader clears the result view with the error "Enumeration yielded no results" see the screenshot Before Running passing Read(),
After passing read()
this is my code,the error happens on getActiveUsers() method.
getDatabases() works just fine. could someone help me? cheers
public partial class automation : System.Web.UI.Page
{
SqlConnection con;
static List<ActiveUsers> activeUsers = new List<ActiveUsers>();
protected void Page_Load(object sender, EventArgs e)
{
ASPxGridView1.DataSource = activeUsers.ToList();
}
public List<ActiveUsers> getDatabases()
{
//passing query
string SqlQuery = "SELECT [WorkspaceName],[MaConfig_Customers].Name FROM [MaConfig_CustomerDatabases] INNER JOIN [MaConfig_Customers] ON [MaConfig_CustomerDatabases].CustomerId = [MaConfig_Customers].CustomerId where [MaConfig_Customers].Status = 0";
//creating connection
string sqlconn = ConfigurationManager.ConnectionStrings["MaxLiveConnectionString"].ConnectionString;
con = new System.Data.SqlClient.SqlConnection(sqlconn);
var cmd = new SqlCommand(SqlQuery, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
List<ActiveUsers> results = new List<ActiveUsers>();
if (reader.Read())
{
while (reader.Read())
{
ActiveUsers company = new ActiveUsers();
company.DatabaseName = String.Format("{0}", reader["WorkspaceName"]);
company.ClientName = String.Format("{0}", reader["Name"]);
results.Add(company);
}
}
con.Close();
return results;
}
public void getActiveUsers()
{
activeUsers.Clear();
List<ActiveUsers> Databases= getDatabases();
SqlConnection conn = new SqlConnection();
string SqlQuery = "select [disabled], [ADMN_Users1].[Record_Id] ,[ADMN_Users].[User_Id] from admn_Users1 inner join [ADMN_Users] on [ADMN_Users1].[record_Id] = [ADMN_Users].[Record_Id] Where [disabled] & 0x2 = 0 ";
for (int i = 0;i < Databases.Count;i++)
{
conn.ConnectionString =
"Data Source=MAXSQLCLUS01;" +
"Initial Catalog=" + Databases[i].ToString()+";"+
"User id=sa;" +
"Password=Max1m1zer;";
var cmd = new SqlCommand(SqlQuery, conn);
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
int NumberOfUsersCounter = 0 ;
//TODO Select Enabled users
if (reader.Read())
{
while (reader.Read())
{
string user = String.Format("{0}", reader["User_Id"]);
//logic to remove system users
if (user.Equals("master", StringComparison.CurrentCultureIgnoreCase))
{
}
else
if (user.Equals("emailuser", StringComparison.CurrentCultureIgnoreCase))
{
}
else
if (user.Equals("webuser", StringComparison.CurrentCultureIgnoreCase))
{
}
else
{
NumberOfUsersCounter++;
}
}
ActiveUsers newEntry = new ActiveUsers();
newEntry.NumberActiveUsers = NumberOfUsersCounter.ToString();
newEntry.DatabaseName = Databases[i].DatabaseName.ToString();
newEntry.ClientName = Databases[i].ClientName.ToString();
activeUsers.Add(newEntry);
}
conn.Close();
//Add to ActiveUsers list
}
ASPxGridView1.AutoGenerateColumns = true;
ASPxGridView1.DataSource = activeUsers.ToList();
ASPxGridView1.DataBind();
}
protected void ASPxButton1_Click(object sender, EventArgs e)
{
getActiveUsers();
}
protected void btnExportExcel_Click(object sender, EventArgs e)
{
ASPxGridView1.DataBind();
ASPxGridViewExporter1.Landscape = true;
ASPxGridViewExporter1.FileName = "User Count Report";
ASPxGridViewExporter1.WriteXlsToResponse();
}
}
}
if (reader.Read())
{
while (reader.Read())
{
ActiveUsers company = new ActiveUsers();
company.DatabaseName = String.Format("{0}", reader["WorkspaceName"]);
company.ClientName = String.Format("{0}", reader["Name"]);
results.Add(company);
}
}
use this
if (reader.HasRows)
{
while (reader.Read())
{
ActiveUsers company = new ActiveUsers();
company.DatabaseName = String.Format("{0}", reader["WorkspaceName"]);
company.ClientName = String.Format("{0}", reader["Name"]);
results.Add(company);
}
}
your if Condition is wrong
if(reader.Read()) ==> is Wrong
Read() is not return boolean Value
use HasRows to check rows in SQLDataReader
You are skipping the first result. if (reader.Read()) { while(reader.Read()) {.... Remove the enclosing if, all it does is see if there is a row and retrieve it but then you do not read it, instead you do it again in the if so the first result is always discarded.
public List<ActiveUsers> getDatabases()
{
//passing query
string SqlQuery = "SELECT [WorkspaceName],[MaConfig_Customers].Name FROM [MaConfig_CustomerDatabases] INNER JOIN [MaConfig_Customers] ON [MaConfig_CustomerDatabases].CustomerId = [MaConfig_Customers].CustomerId where [MaConfig_Customers].Status = 0";
//creating connection
string sqlconn = ConfigurationManager.ConnectionStrings["MaxLiveConnectionString"].ConnectionString;
using(con = new System.Data.SqlClient.SqlConnection(sqlconn))
using(var cmd = new SqlCommand(SqlQuery, con))
{
con.Open();
using(SqlDataReader reader = cmd.ExecuteReader())
{
List<ActiveUsers> results = new List<ActiveUsers>();
while (reader.Read())
{
ActiveUsers company = new ActiveUsers();
company.DatabaseName = reader.GetString(0);
company.ClientName = reader.GetString(1);
results.Add(company);
}
}
}
return results;
}
Side notes:
company.DatabaseName = String.Format("{0}", reader["WorkspaceName"]) would be better written as company.DatabaseName = reader.GetString(0). The same goes for the next line. No need to use string.Format and you are specifying the columns and order in the query so use the ordinal index so get the native value.
I would recommend you wrap the SqlConnection and SqlDataReader in using blocks to ensure they are closed/disposed after use even in the event of an exception.

C# update statement not updating when update button clicked

i am creating c# project so far insert and delete buttons are working but when i hit update button it gives data has not been updated and i cant see what is wrong with my code please help
public bool Update(Classre c)
{
bool isSuccess = false;
SqlConnection conn = new SqlConnection(myconnstring);
try
{
string sql = "UPDATE Class SET ClassName=#ClassName,ClassLevel=#ClassLevel WHERE ClassID=#ClassID";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#ClassName", c.ClassName);
cmd.Parameters.AddWithValue("#ClassLevel", c.ClassLevel);
conn.Open();
int rows = cmd.ExecuteNonQuery();
if (rows > 0)
{
isSuccess = true;
}
else
{
isSuccess = false;
}
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
return isSuccess;
}
and this is my update button code where i call the class that holds my update code
private void button3_Click(object sender, EventArgs e)
{
c.ClassID = int.Parse(textBox1.Text);
c.ClassName = textBox2.Text;
c.ClassLevel = comboBox1.Text;
bool success = c.Update(c);
if (success == true)
{
// label4.Text = "Data Has been updated";
MessageBox.Show("Data Has been updated");
DataTable dt = c.Select();
dataGridView1.DataSource = dt;
}
else
{
//label4.Text = "Data Has not been updated";
MessageBox.Show("Data Has not been updated");
}
}
I would prefer to use a stored procedure instead of pass through sql but you could greatly simplify this. As stated above your try/catch is worse than not having one because it squelches the error.
public bool Update(Classre c)
{
USING(SqlConnection conn = new SqlConnection(myconnstring))
{
string sql = "UPDATE Class SET ClassName = #ClassName, ClassLevel = #ClassLevel WHERE ClassID = #ClassID";
USING(SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add("#ClassName", SqlDbType.VarChar, 4000).Value = c.ClassName;
cmd.Parameters.Add("#ClassLevel", SqlDbType.Int).Value = c.ClassLevel;
cmd.Parameters.Add("#ClassID", SqlDbType.Int).Value = c.ClassID;
conn.Open();
int rows = cmd.ExecuteNonQuery();
return rows > 0;
}
}
}

Exit out of datareader before else, in if-else statement

I would like to find a way to exit out of datareader after the if statement so that I can execute the insert query in else statement. Is there a way to do it?
I am getting the error that dr is still open and hence cannot perform the below query.
sVendorDetails.VendorID = insertcmd.ExecuteNonQuery();
Here is the code:
public class VendorDetails
{
int _VendorID;
string _VendorName;
public int VendorID
{
set { _VendorID = value; }
get { return _VendorID; }
}
public string VendorName
{
set { _VendorName = value; }
get { return _VendorName; }
}
}
public VendorDetails VendorCheck(string sVendorName)
{
SqlCommand cmd = new SqlCommand("dbo.usp_GetVendorByVendorName", myConnection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#VendorName", SqlDbType.VarChar));
cmd.Parameters["#VendorName"].Value = sVendorName;
VendorDetails sVendorDetails = null;
try
{
myConnection.Open();
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
sVendorDetails = new VendorDetails();
sVendorDetails.VendorID = ((int)dr["VendorID"]);
sVendorDetails.VendorName = ((string)dr["VendorName"]).ToUpper().Trim();
}
}
else if (dr.HasRows!= true)
{
ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('VendorName:" + sVendorName + " not found. Inserting Vendor details into Vendor and Invoice table.')", true);
SqlCommand insertcmd = new SqlCommand("dbo.InsertVendorName", myConnection);
insertcmd.CommandType = CommandType.StoredProcedure;
insertcmd.Parameters.Add(new SqlParameter("#VendorName", SqlDbType.VarChar));
insertcmd.Parameters["#VendorName"].Value = sVendorName;
sVendorDetails = new VendorDetails();
sVendorDetails.VendorID = insertcmd.ExecuteNonQuery();
sVendorDetails.VendorName = sVendorName;
}
dr.Close();
return sVendorDetails;
}
catch (SqlException err)
{
throw new ApplicationException("DB usp_GetVendorByVendorName Error: " + err.Message);
}
finally
{
myConnection.Close();
}
}
You will need to close/dispose of your DataReader prior to reusing the connection, as it's still being used.
Maybe something like this?
var readerHasRows = false;
using (var dr = cmd.ExecuteReader())
{
readerHasRows = dr.HasRows;
if(readerHasRows)
{
while (dr.Read())
{
sVendorDetails = new VendorDetails();
sVendorDetails.VendorID = ((int)dr["VendorID"]);
sVendorDetails.VendorName = ((string)dr["VendorName"]).ToUpper().Trim();
}
}
}
if(!readerHasRows)
{
ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('VendorName:" + sVendorName + " not found. Inserting Vendor details into Vendor and Invoice table.')", true);
SqlCommand insertcmd = new SqlCommand("dbo.InsertVendorName", myConnection);
insertcmd.CommandType = CommandType.StoredProcedure;
insertcmd.Parameters.Add(new SqlParameter("#VendorName", SqlDbType.VarChar));
insertcmd.Parameters["#VendorName"].Value = sVendorName;
sVendorDetails = new VendorDetails();
VendorDetails.VendorID = insertcmd.ExecuteNonQuery();
sVendorDetails.VendorName = sVendorName;
}
There are a few things I would like to mention
Your main issue is that you are not closing your DataReader. You can use the using statement for it
You don't need to explicitly open and close the SqlConnection. The SqlCommand object will do it as needed.
You don't need to check with if (dr.HasRows) and then check again in while (dr.Read()). Also, you don't need to loop to pick up only one row of data.
Ideally, I would put the "Fetch" part in a separate function and the "insert" in a separate function, so the functions stay small and reusable.
Your pattern is superfluous if (flag) {TakeAction();} else if (!flag) {TakeAction2();}. Every time the code hits theelse, it will also hit theif (!flag)`
sVendorDetails.VendorID = insertcmd.ExecuteNonQuery(); line looks fishy. If your Stored Procedure returns the VendorId, then you should use ExecuteScalar. Currently it is just storing 1 in all case since you are presumably inserting one row.
Don't discard the original SqlException when creating a custom ApplicationException. Upstream system might want to know more details than you are passing. Pass it along as the InnerException
I have also changed some stylistic aspects:
The variable names changed to the more commonly used camelCase, instead of the incorrectly used Hungarian Notation (sVendorDetails instead of oVendorDetails)
Brace in K&R style
Used var when the right side is a new statement
Use Object Initializers instead of creation+assignment
Below is the code
public VendorDetails VendorCheck(string vendorName, SqlConnection myConnection) {
try {
return GetVendor(vendorName, myConnection) ?? InsertVendor(vendorName, myConnection);
} catch (SqlException err) {
throw new ApplicationException("DB usp_GetVendorByVendorName Error: " + err.Message, err);
}
}
VendorDetails GetVendor(string vendorName, SqlConnection myConnection) {
using (var cmd = new SqlCommand("dbo.usp_GetVendorByVendorName", myConnection)) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#VendorName", SqlDbType.VarChar));
cmd.Parameters["#VendorName"].Value = vendorName;
using (SqlDataReader dr = cmd.ExecuteReader()) {
ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('VendorName:" + vendorName + " not found. Inserting Vendor details into Vendor and Invoice table.')", true); // TODO: Does this really belong here!?!?
if (dr.Read()) {
return new VendorDetails {
VendorID = ((int)dr["VendorID"]),
VendorName = ((string)dr["VendorName"]).ToUpper().Trim()
};
}
}
}
return null;
}
VendorDetails InsertVendor(string vendorName, SqlConnection myConnection) {
using (var insertcmd = new SqlCommand("dbo.InsertVendorName", myConnection)) {
insertcmd.CommandType = CommandType.StoredProcedure;
insertcmd.Parameters.Add(new SqlParameter("#VendorName", SqlDbType.VarChar));
insertcmd.Parameters["#VendorName"].Value = vendorName;
return new VendorDetails {
VendorID = (int)insertcmd.ExecuteScalar(),
VendorName = vendorName
};
}
}

Retrieving a value from a C# DataLibrary to be placed in ASP.Net label

I have a DataClassLibrary attached to my ASP.Net project. I use it to access the database to get my values. I want to take the values given in the Line1 class and put them in the corresponding label. I tried DataLibraryClass.Line1 NewDataA = new DataLibraryClass.Line1(); but it gives me a zero I know that they have values. Could it be that my NewDataA = new is causing it to return zero? I also used breakpoints in the Line1 class and it never reaches the database query. How can I get the data I need into the labels properly?
DataLibraryClass
Line1:
var sqlString = new StringBuilder();
sqlString.Append("SELECT CaseNum6, CaseNum9, Group, Completion ");
sqlString.Append("FROM WorkOrder ");
sqlString.Append("WHERE Group = 1 OR Group = 2 ");
sqlString.Append("AND Completion = 0 ");
SqlDataReader reader = null;
SqlConnection dbConn = DBHelper.getConnection();
SqlParameter[] parameters = new SqlParameter[] { new SqlParameter("#CaseNum6", CaseNum6 )};
try
{
reader = DBHelper.executeQuery(dbConn, sqlString.ToString(), parameters);
if (reader != null)
{
if (reader.Read())
{
CaseNum6 = (int)reader["CaseNum6"];
CaseNum9 = (int)reader["CaseNum9"];
Group = (int)reader["Group"];
Completion = (bool)reader["Completion"];
}
else
throw new Exception("No record returned");
reader.Close();
reader.Dispose();
dbConn.Close();
dbConn.Dispose();
DataLibraryClass
DBHelper:
private DBHelper() { }
public static SqlConnection getConnection()
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["Connection"].ConnectionString);
}
public static SqlConnection getFRESHConnection()
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["FRESHConnection"].ConnectionString);
}
public static SqlDataReader executeQuery(SqlConnection dbConn, string sqlString, SqlParameter[] parameters)
{
SqlCommand cmd = null;
SqlDataReader reader = null;
try
{
if (dbConn.State == ConnectionState.Closed)
dbConn.Open();
cmd = dbConn.CreateCommand();
cmd.CommandText = sqlString;
if (parameters != null)
{
cmd.Parameters.AddRange(parameters);
}
reader = cmd.ExecuteReader();
cmd.Dispose();
}
catch (Exception ex)
{
throw ex;
}
return reader;
Code behind ASP page:
DataClassLibrary.LineAData NewDataA = new DataClassLibrary.LineAData();
DataClassLibrary.LineBData NewDataB = new DataClassLibrary.LineBData();
protected void Page_Load(object sender, EventArgs e)
{
L1.Text = NewDataA.CaseNum6.ToString();
L2.Text = NewDataA.CaseNum9.ToString();
L4.Text = NewDataB.CaseNum6.ToString();
L5.Text = NewDataB.CaseGNum9.ToString();
}
Upon setting up the webpage I failed to realize the behind code was set to .vb not .cs which is why everything was not working.

Categories