Update sql database without blanks fields - c#

I am trying to figure out a way for my program not to update the sql database if some fields are blank when I hit the submit form. Right now when I submit it to the sql database, if the fields are blank, it updates it as blank. Is there a way for my code not to behave like this?
Thanks
//field names in the table
string update = #"UPDATE Master_List
SET Date_Complete1 = #Date_Complete1, Pass_Fail = #Pass_Fail, CRC_Number = #CRC_Number, QN_Number = #QN_Number, Notes = #Notes WHERE Job_Number = #Job_Number"; //parameter names
using (SqlConnection conn = new SqlConnection(connString)) //using allows disposing of low level resources
{
try
{
conn.Open();//open new connection
command = new SqlCommand(update, conn); // create the new sql command object
// Read value from form and save to the table
command.Parameters.AddWithValue(#"Job_Number", jobTxt.Text);
command.Parameters.AddWithValue(#"Pass_Fail", comboBox1.Text);
command.Parameters.AddWithValue(#"Date_Complete1", opBox1.Text);
command.Parameters.AddWithValue(#"CRC_Number", crcTxt.Text);
command.Parameters.AddWithValue(#"QN_Number", qnTxt.Text);
command.Parameters.AddWithValue(#"Notes", notesTxt.Text);
command.ExecuteNonQuery(); // Push form into the table
}
catch (Exception ex)
{
MessageBox.Show(ex.Message); // If there is something wrong, show the user message
}
}

Assuming that you want to update some of the fields if one or more fields are blank, then you can do this:
UPDATE Master_List
SET Date_Complete1 = ISNULL(NULLIF(#Date_Complete1,''),Date_Complete1),
Pass_Fail = ISNULL(NULLIF(#Pass_Fail,''),Pass_Fail),
CRC_Number = ISNULL(NULLIF(#CRC_Number,''),CRC_Number),
QN_Number = ISNULL(NULLIF(#QN_Number,''),QN_Number),
Notes = ISNULL(NULLIF(#Notes,''),Notes)
WHERE Job_Number = #Job_Number
If you don't want any fields to update if any fields are blank, then just check them in an if statement.

Perform checks on your input data before your sql code is executed.
simply return out of the function if any checks you want to do fail e.g.
If(string.IsNullOrEmpty(variable to check))
... Return or configure error message for user ...
Or perform some logic to show the user you dont want blank fields.

If you are going to validate that you should change your database field properties to do that task.
if you want to do this with some code you should add something like this:
bool val = true;
if (jobTxt.Text.Trim() == string.Empty) {
val = false;
}
if(val==true){
command.ExecuteNonQuery();
}
else{
MessageBox.Show("Some field is empty")
}
and repite the sentence if for each textbox you want to do a validation.
i hope this help you.
You can say which textbox is empty on the else sentences on the textbox.

Related

How can I move data query away from user form. Winform C#

I'm completely new to C# programming and I'm trying to learn on my own. Currently I'm building a mini-project to exercise.
I understand that the user layer should not have any data query for security reasons perhaps?
So I have created a separate Data Access class to retrieve data. This is what my data access class looks like(I'll be using stored procedures for better security once I learn how to use it):
public class DataAccess
{
public List<Customer> FilteredCustomersList(string name)
{
using (IDbConnection connection = new MySql.Data.MySqlClient.MySqlConnection(Helper.CnnVal("FineCreteDB")))
{
var output = connection.Query<Customer>($"SELECT * from `Customers` WHERE `Cust_Name` LIKE '{name}'").ToList();
return output;
}
}
Basically I send over a string from the user form to query the database, the data is retrieved and stored in a list. User form:
private void RetrieveData()
{
try
{
DataAccess db = new DataAccess();
filteredcustomers = db.FilteredCustomersList(CustomerNameTxtBox_AutoComplete.Text);
ntn_num = filteredcustomers.Select(x => x.Cust_NTN).ElementAt(0);
strn_num = filteredcustomers.Select(x => x.Cust_STRN).ElementAt(0);
address = filteredcustomers.Select(x => x.Cust_Address).ElementAt(0);
phone_num = filteredcustomers.Select(x => x.Cust_Phone).ElementAt(0);
id_num = filteredcustomers.Select(x => x.Cust_ID).ElementAt(0);
}
catch (Exception)
{
MessageBox.Show("Customer not found. If customer was recently added, try updating DB.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
DataAccess db = new DataAccess();
filteredcustomers = db.AllCustomersList();
ntn_num = "";
strn_num = "";
address = "";
phone_num = "";
}
}
On the user form side, "filteredcustomers" holds the list of data sent back, now here is the problem: I use the filteredcustomers list to extract the different column values like so:
address = filteredcustomers.Select(x => x.Cust_Address).ElementAt(0);
and then use them to populate the respective textboxes like:
Address_TxtBox.Text = address;
Everything works fine, but I don't want the userform to have these queries for all individual columns, because from what I've understood so far, this is bad programming and bad for security as well.
Can anyone guide me how I can keep the values in Data Access layer and just call them into my form?
I'm sorry if this is a long post, I'm just learning and wanted to be as detailed as possible.
You're already doing everything reasonably correctly as per how Dapper is to be used. Dapper doesn't maintain a local graph of entities from the db, track changes to it and automatically save them. If you want that, use something like EF
For dapper you retrieve data with a SELECT and send it back with an UPDATE
If you're only expecting one Customer for the name, do this:
var output = connection.QueryFirstOrDefault<Customer>($"SELECT * from `Customers` WHERE `Cust_Name` LIKE #n", new { n = name });
https://dapper-tutorial.net/queryfirst
This will return just one customer instance (or null; check it!) meaning you can tidy up your form code to:
c = db.FilteredCustomer(CustomerNameTxtBox_AutoComplete.Text);
ntn_num = c?.Cust_NTN;
strn_num = c?.Cust_STRN;
And so on
Your "if customer was recently added try updating db" doesn't really make sense- the query is done live, so the db is about as up to date as it can be

Can't get a value out an ASP.NET hidden field

I am going through a YouTube video, to learn ASP.NET. I've gotten it to work for the most part, with a somewhat major caveat: I can't retrieve a value from a hidden field ID. Because of that, I don't have a value to send to a stored procedure to create or update.
The commented out line is the original statement. When I have that then execute
.ExecuteNonQuery, I get the following error:
Procedure or function 'ResourceCreateOrUpdate' expects parameter '#ResourceID', which was not supplied
When I try to display hfResourceID, I have nothing when trying to pass 0, for a create, or the ResourceID value, i.e. 1. That value however, doesn't get there. I know the stored procedure works because I can execute it in SQL Server Management.
I tried moving hfResourceID to a string, then a integer value, but I seem to be having problems creating the if/else: everything is marked as an error. When I hover over the lines, I get the following message, which pretty much leave me clueless:
"Embedded statement cannot be a declaration or labeled statement".
Would I be able to get any pointers on how to clear up my error, please? Thanks.
2017-10-13 # 10:38: code updated
<asp:HiddenField ID="hfResourceID" runat="server" />
protected void btnSave_Click(object sender, EventArgs e)
{
int intResourceID = 0;
bool boolIDHasValue = true;
try
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
catch (Exception ex)
{
lblErrorMessage.Text = ex.Message;
boolIDHasValue = false;
}
if (boolIDHasValue)
{
if (sqlconnODRConnection.State == System.Data.ConnectionState.Closed)
sqlconnODRConnection.Open();
SqlCommand sqlcmdCreateOrUpdate = new SqlCommand("ResourceCreateOrUpdate", sqlconnODRConnection);
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#ResourceID", intResourceID);
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#Status", txtStatus.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#FirstName", txtFirstName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#MiddleName", txtMiddleName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#LastName", txtLastName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#NickName", txtNickName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#Gender", txtGender.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#USCitizen", txtUSCitizen.Text.Trim());
sqlcmdCreateOrUpdate.ExecuteNonQuery();
sqlconnODRConnection.Close();
string strResourceID = hfResourceID.Value;
Clear();
if (strResourceID == "")
lblSuccessMessage.Text = "Saved Successfully";
else
lblSuccessMessage.Text = "Updated Successfully";
FillGridView();
}
}
There are a few issues with the code you copied from that video. But here a snippet as to how it should be done. I've added 3 ways to convert from the HiddenField value to an actual int. Which one you use can depend on how you want to handle errors, 0 values etc. Not included in the snippet, but I like to check for IsNullOrEmpty while using Trim(), that gets rid of spaces that might make the value non-convertible if (!string.IsNullOrEmpty(hfResourceID.Value.Trim())).
int intResourceID = 0;
//this will try to convert but you won't see exeptions when failed
Int32.TryParse(hfResourceID.Value, out intResourceID);
//checks if there is a value in the hiddenfield, but throws yellow screen if not convertible
if (!string.IsNullOrEmpty(hfResourceID.Value))
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
//catch an error when the value is not convertible, can be wrapped with !string.IsNullOrEmpty(hfResourceID.Value)
try
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
catch (Exception ex)
{
//handle the error, can be seen with ex.Message
}
//if the hidden value is still 0 (for whatever reason) you might not want to execute the query
//so the next part will return and stop executing the rest of the code
if (intResourceID == 0)
{
return;
}
//update the database, using 'using' will ensure proper closure of the connection and disposing of any objects
using (SqlConnection connection = new SqlConnection("myConnectionString"))
using (SqlCommand command = new SqlCommand("ResourceCreateOrUpdate", connection))
{
//set the command type and add the parameters
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#ResourceID", SqlDbType.Int).Value = intResourceID;
try
{
//open the database connection and execute the command
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
//there was an error opening the database connection or with the command, can be viewed with ex.Message
}
}
Your error regarding the embedded statement is because you a declaring
if (strResourceID == "")
int intResourceID = 0;
else
int intResourceID = (Convert.ToInt32(hfResourceID.Value));
When decalring a variable directly after an If or else then you need your curly brackets. So...
if (strResourceID == "")
{
int intResourceID = 0;
}
else
{
int intResourceID = (Convert.ToInt32(hfResourceID.Value));
}
As for your other issues I would need to see your client side code.
Take a look on ASP code, specifically the way you are setting hidden field value. I guess it is properly marked as runat=server but maybe some problem is going on in your asp.net code, try to debug client code by using: console.log function and see the output in your console browser.

SubmitChanges not updating, but inserts new record. LINQ to SQL

I am having difficulties UPDATING the databes via LINQ to SQL, inserting a new record works fine.
The code correctly inserts a new row and adds a primary key, the issue I am having is when I go to update (chnage a value that is already in the database) that same row the database is not updating, it is the else part of the code that does not work correctly. This is strange b/c the DB is properly connected and functioning through the fact that the DataContext inserts a new row with no issues. Checking the database confirms this.
This is the code,
using System;
using System.Collections.Generic;
using System.Linq;
using Cost = Invoices.Tenant_Cost_TBL;
namespace Invoices
{
class CollectionGridEvents
{
static string conn = Settings.Default.Invoice_DbConnectionString;
public static void CostDataGridCellEditing(DataGridRowEditEndingEventArgs e)
{
using (DatabaseDataContext DataContext = new DatabaseDataContext(conn))
{
var sDselectedRow = e.Row.Item as Cost;
if (sDselectedRow == null) return;
if (sDselectedRow.ID == 0)
{
sDselectedRow.ID = DateTime.UtcNow.Ticks;
DataContext.Tenant_Cost_TBLs.InsertOnSubmit(sDselectedRow);
}
else
{
// these two lines are just for debuging
long lineToUpdateID = 636154619329526649; // this is the line to be updated primary key
long id = sDselectedRow.ID; // this is to check the primary key on selected line is same
// these 3 lines are to ensure I am entering actual data into the DB
int? amount = sDselectedRow.Cost_Amount;
string name = sDselectedRow.Cost_Name;
int? quantity = sDselectedRow.Cost_Quantity;
sDselectedRow.Cost_Amount = amount;
sDselectedRow.Cost_Name = name;
sDselectedRow.Cost_Quantity = quantity;
}
try
{
DataContext.SubmitChanges();
}
catch (Exception ex)
{
Alert.Error("Did not save", "Error", ex);
}
}
}
}
}
And I am calling the method from this,
private void CostDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
CollectionGridEvents.CostDataGridCellEditing(e);
}
The lineToUpdateID is copied dirrectly from the database and is just there to check against the currently selected rows primary key is the same, so I know I am trying to update the same row.
I have looked through as many of the same type of issues here on SO , such as this one Linq-to-Sql SubmitChanges not updating fields … why?. But still no closer to finding out what is going wrong.
Any ideas would be much appreciated.
EDIT: Cost is just short hand of this using Cost = Invoices.Tenant_Cost_TBL;
You cannot do that. You need to get the record out of the database and then update that record. Then save it back. Like this:
else
{
// first get it
var query =
from ord in DataContext.Tenant_Cost_TBLs
where ord.lineToUpdateID = 636154619329526649
select ord;
// then update it
// Most likely you will have one record here
foreach (Tenant_Cost_TBLs ord in query)
{
ord.Cost_Amount = sDselectedRow.Cost_Amount;
// ... and the rest
// Insert any additional changes to column values.
}
}
try
{
DataContext.SubmitChanges();
}
catch (Exception ex)
{
Alert.Error("Did not save", "Error", ex);
}
Here is an example you can follow.
Or you can use a direct query if you do not want to select first.
DataContext.ExecuteCommand("update Tenant_Cost_TBLs set Cost_Amount =0 where ...", null);
Your object (Cost) is not attached to DB context. You should attach it then save changes. Check solution here

Check if user ID exist in SQL database

I'm a beginner programmer and I'm writing a C# application that makes a query to a database. However I am wondering how could I check that an ID exists (ID is entered by user in the console application) and if it doesn't, display a message.
Here's my code:
Console.WriteLine("enter ID");
try
{
var province_id = Convert.ToInt32(Console.ReadLine());
var aquery2 = from test in context.BusinessEntityAddress
where test.Address.StateProvinceID == province_id
group test.BusinessEntity.Person.LastName by new { test.BusinessEntityID, test.BusinessEntity.Person.LastName, test.BusinessEntity.Person.FirstName }
into balk
select new {
...
};
Didn't paste the whole code but this is the part my question is about. At the line
where test.Address.StateProvinceID == userid
I would like to check if that ID exist in the database, and if it doesn't, display a message. I don't know how to do that.
Note that all the code is already in a try{}catch{} because I also need to ensure that the user input is an integer.
Thank you
It seems like you're trying to do a lot more then just search for a user ID in your question? You seem to be saying StateProvinceId is a user Id? In which case a simple test like this should suffice:
if (!context.Addresses.Any(a => a.StateProvinceID == userid))
{
Console.WriteLine("User doesn't exist");
}
Although, it would seem more logical to look in a users table. EG, context.Users. Which would hence question why you are doing a group by (which shouldn't be needed).
You will need to add each data object to your context, but if you could elaborate more on what exactly isn't working, we can help more.
You don't need to run the code inside a try for that, instead first you have to check for the existence of the user:
int number;
//check if the userId is an integer
if(!int.TryParse(userId, out number)){
Console.WriteLine("Please enter a valid interger!!");
return;
}
var beAddress = context.BusinessEntityAddress;
//check for the userId exist in the DB
var flag = beAddress.Any(a => a.Address.StateProvinceID == number);
if(flag){
//do something if the user exist
}
else{
//do something else if the user doesn't exist
}
For checking if the string is a valid integer you should use int.TryParse("8", NumberStyles.Integer, System.Globalization.NumberFormatInfo.InvariantInfo, out number);, this way you are not just checking if the string is a number but if is an integer.
You shouldn't use try-catch for a classic user error, like number parsing. int.TryParse() is made for this :
// get rid of the try-catch, you wont need it anymore
int userid;
var input = Console.ReadLine();
if (!int.TryParse(input, out userID))
{
Console.WriteLine("Invalid input : '{0}' is not a number", input);
return;
}
var aquery2 = from test in context.BusinessEntityAddress
where test.Address.StateProvinceID == userid
group test.BusinessEntity.Person.LastName by new { test.BusinessEntityID, test.BusinessEntity.Person.LastName, test.BusinessEntity.Person.FirstName } into balk
select new
{
/* ... */
};
if (!aquery2.Any())
{
// not found... display a message
}
else
{
// found... do stuffs
}
This is the code which I'm using. I don't know about console application but know little bit about C# and SQL. I'm not sure I understood clearly but just hope this might help you. Thank you.
bool idfound; (declare in the field of a Class)
private void buttonIDcheck_Click(object sender, RoutedEventArgs e)
(a Event which has to be created by Visual Studio, not manually)
{
SqlConnection Conn = new SqlConnection();
Conn.ConnectionString = yourConnectionString;
Conn.Open();
SqlCommand check_idexistcomm = new SqlCommand();
check_idexistcomm.Connection = Conn;
check_idexistcomm.CommandText = "SELECT id FROM yourtable";
var check_idexistda = new SqlDataAdapter(check_idexistcomm);
SqlDataReader check_idexistreader = check_idexistcomm.ExecuteReader();
while (check_idexistreader.Read())
{
if (check_idexistreader["id"].ToString()== text value inputed by user here)
{
idfound = true;
break;
}
}
check_idexistreader.Close();
Conn.Close();
if (idfound=true)
{
your code here to accept the user as authorized
}
else
{
MessageBox.Show("Sorry, you're not authorized");
}
}

asp.net c# server not seeing change in data from client

i have an asp.net webform where the user can enter data and submit into a database table on sql-server-2008
the user picks the primary key of the record he wants to edit by going to the URL http://someurl/default.aspx?primarykey=123
based on the primary key the webform is succesfully filled out
the user can make changes to any data and resubmit it to be updated in the database for that specific PK
here is how i grab data from the userform:
public LOMDLL.Main_Lom_Form PopulateMainForm()
{
//populate class
LOMDLL.Main_Lom_Form TheForm = new LOMDLL.Main_Lom_Form();
try
{
TheForm.received_date = received_dateTextbox.Text.ToDateTime();
TheForm.site_of_occurrence = site_of_occurrenceTextBox.Text.ToUpper();
TheForm.occurrence_date = occurrence_dateTextBox.Text.ToDateTime();
TheForm.report_by = report_byTextBox.Text;
if (RadioButtonList1.SelectedValue != "Other:")
TheForm.identified_by = RadioButtonList1.SelectedValue;
else
TheForm.identified_by = "Other: " + otherTextBox.Text;
TheForm.practice_code = txtPracticeCode.Text.ToUpper();
TheForm.comments = txtComments.Text;
TheForm.report_date = report_dateTextBox.Text.ToDateTime();
//TheForm.windows_user = WindowsIdentity.GetCurrent().Name;
TheForm.windows_user = HttpContext.Current.User.Identity.Name.ToString();
TheForm.computer_name = System.Environment.MachineName;
TheForm.time_stamp = DateTime.Now;
}
catch (Exception e)
{
}
return TheForm;
}
it is returning OLD data. it returns what was in the fields BEFORE the user updated the data in the textboxes.
another words when i debug, and i look at the values that are being stored in the textboxes they DO NOT reflect the changes made by the user. the values are the same as they are currently in the database before the update!
what am i doing wrong?
is there some kind of disconnect between client and server?
I would check your bindings when you load the page. Chances are you are re-binding your page from your database before you try to read the changed values.
Check your Page_Load and make sure you are only binding your page with database information when !Page.IsPostBack and not every time you load your page.

Categories

Resources